在我的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)在同一行。
这不是将我的动作链接在一起的正确方法吗?
明智的选择,我必须一个接一个地做。
答案 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。)