尝试将多个动作链接到我的组件中

时间:2018-09-04 00:32:48

标签: reactjs redux-thunk

在我的react组件中,我试图将多个动作链接在一起,例如:

componentDidMount() {
  dispatch(Actions.fetchUser(userId)).then(() => {
    dispatch(Actions.fetchAbc(abcId)).then(() => {
      dispatch(Actions.fetchDef(defId));
    });
  });     
}

每个动作都遵循与fetchUser相同的模式,并在该模式下返回调度:

fetchUser: (userId) => {
  return dispatch => {
    let url = "....";
    axios.get(url)
      .then(function(resp) {        
        dispatch({
          type: Constants.SomeAction,
          user: resp.data.user,
        });
      });
  };
},

在我的组件中,我看到一个错误:

  

未捕获的TypeError:无法读取未定义的属性'then'

错误与第一个.then调用(fetchUser)在同一行。

这不是将我的动作链接在一起的正确方法吗?

明智的选择,我必须一个接一个地做。

1 个答案:

答案 0 :(得分:2)

调度thunk返回thunk函数的返回值,但是您的函数没有返回任何值。试试:

fetchUser: (userId) => {
  return dispatch => {
    let url = "....";
    // return the promise so you can chain on it
    return axios.get(url)
      .then(function(resp) {        
        dispatch({
          type: Constants.SomeAction,
          user: resp.data.user,
        });
      });
  };
},

您需要确保您返回的是axios返回的承诺,因为这就是您想要与随后的then绑定的内容。


从更广泛的角度来看,必须确保按特定顺序分派操作,这种情况基于操作是同步还是异步(异步操作通常会返回承诺)而有所不同。

同步事件很容易,您只需按顺序调用它们即可:

dispatch(syncAction1())
dispatch(syncAction2())
dispatch(syncAction3())

对于异步操作,您需要确保每个操作都返回一个promise,然后将它们链接起来(重写componentDidMount函数以指出其他一些问题):

dispatch(Actions.fetchUser(userId))
  // You need to ensure that your handler functions returns the result of the
  // next async dispatch
  .then(() => {
    return dispatch(Actions.fetchAbc(abcId))
  })
  // More simply, if you're only doing on thing then you can use the shorter
  // form of arrow function, which implicitly returns the result      
  .then(() => dispatch(Actions.fetchDef(defId))

如果遇到需要将两者结合的情况,也可以这样做:

dispatch(syncAction1())
dispatch(asyncAction2())
  .then(() => {
    dispatch(syncAction3())
    return dispatch(asyncAction4())
  })
  .then(() => dispatch(asyncAction5))

(异步操作是返回承诺的thunk,但同步操作可以是普通对象或同步thunk。)