Redux:在 React 视图事件上触发异步数据获取

Redux: trigger async data fetch on React view event

完全是 React/Redux 的新手,并且对创建组件等的所有不同方法感到非常困惑。我已经阅读了 Redux 的 async docs 并设法在页面加载时加载异步数据,但现在我想用一个按钮来触发数据下载。

到目前为止,我在 render 函数中有一个组件。

<button onClick={() => dispatch(getEntry('dummy'))}> Get some data< /button>

这正在到达我的动作创作者

export function getEntry(apiroute) {
  return {
    type: GET_ENTRY,
    apiroute
  };
}

redux 将其传递给我的减速器

export function entry(state = initialState, action) {
  switch (action.type) {
  case 'GET_ENTRY':
    return Object.assign({}, state, {
      fetching : true
    });

我可以在我的日志中看到该操作正在更改状态。

在我的操作文件中,我有这段代码,我知道如果我将它连接到我的应用程序的引导中,它就可以工作。

export function fetchEntry() {
  return function(dispatch) {
    return window.fetch('/google.json')
      .then(response => response.json())
      .then(json => dispatch(recEntry(json)));    
  }
}

但是我应该在点击按钮后按上面的顺序在哪里以及如何调用 fetchEntry

好的,不确定这是否是唯一的方法,但这在我的组件中有效

constructor(props) {
    super(props);
    this.getdata = this.getdata.bind(this);
}

getdata(evt) {
    const { dispatch } = this.props;
    dispatch(getEntry('getdata'));
    fetchEntry()(dispatch);
}

render() {
    return (
        <div>
            <button onClick={this.getdata}> Get some data2</button>

基本上我会向商店发送一条消息,告知更新正在开始,然后开始更新。

欢迎确认这是一个惯用模式。

执行异步的惯用方法是使用 redux-thunkredux-promise 之类的东西。 redux-thunk 我认为更常见。您在 fetchEntry 函数中使用了 thunk 模式,但我认为这不是惯用的。从顶部开始:

您的按钮代码看起来不错。

您的 getEntry 动作创建器有点用词不当。 initiateGetEntry,您使用它的次数更多,对吧?

使用 redux-thunk,您可以将两个动作创建器组合成一个 thunk 动作创建器:

export function getEntry() {
  return function(dispatch) {
    dispatch({ type: 'GET_ENTRY_INITIATE' });
    fetch('google.json)
      .then(function(res) { dispatch({ type: 'GET_ENTRY_SUCCESS, payload: res }) }
      .catch(function(res) { dispatch({ type: 'GET_ENTRY_FAIL' });
  } 
}

reducer 将与您拥有的类似:

export function entry(state = initialState, action) {
  switch (action.type) {
  case 'GET_ENTRY_INITIATE':
    return Object.assign({}, state, { fetching : true });
  case 'GET_ENTRY_SUCCESS':
    return Object.assign({}, state, action.payload, { fetching: false });
  case 'GET_ENTRY_FAIL':
    return Object.assign({}, state, { fetching: false, error: 'Some error' });
  default:
    return state;
}

然后,您的 UI 代码可以正常工作:

<button onClick={() => dispatch(getEntry('dummy'))}> Get some data< /button>