我对React和Redux很陌生。我想使用redux-promise-middleware链接多个API调用,并执行以下操作:
locationActions.js:
import { visitLocation } from '../services/actionService';
export const VISIT_LOCATION = 'VISIT_LOCATION';
export const VISIT_LOCATION_PENDING = 'VISIT_LOCATION_PENDING';
export const VISIT_LOCATION_FULFILLED = 'VISIT_LOCATION_FULFILLED';
export const VISIT_LOCATION_REJECTED = 'VISIT_LOCATION_REJECTED';
const visitLocationAction = (characterId, location) => ({
type: VISIT_LOCATION,
// visitLocation returns a new promise
payload: visitLocation(characterId, location)
});
export { visitLocationAction as visitLocation };
我使用mapDispatchToProps
从我的React组件中调度此动作:
const mapDispatchToProps = dispatch => (
bindActionCreators({ visitLocation }, dispatch)
);
这有效!但是,我想在visitLocation
解决并完成后再调度其他操作。我无法调用Promise.then()
,因为它不提供dispatch
方法,因此不能将我的操作“绑定”到减速器。
教程提到我应该打电话给dispatch(secondAction())
,但我的动作创建者中没有可用的调度。
有人可以向我指出我在想什么吗?
编辑:
根据第一个答案的建议,我尝试了以下方法:
import { visitLocation } from '../services/locationService';
import { fetchSomething } from '../services/otherService';
const visitLocationAction = (characterId, location) => {
return (dispatch) => {
return dispatch(visitLocation(characterId, location))
.then(() => dispatch(fetchSomething()));
};
};
export { visitLocationAction as visitLocation };
但是我得到了action:undefined和以下错误:
Error: Actions must be plain objects. Use custom middleware for async actions.
at dispatch (redux.js:200)
at redux-logger.js:1
答案 0 :(得分:3)
教程提到我应该打电话给
Shell App.Path & "\winhlp32.exe myhelpfile"
,但我的动作创建者中没有可用的调度。
首先让我回答您问题的这一部分。如第一个答案所述,您需要Redux Thunk(一种中间件)才能在动作创建者中使用dispatch(secondAction())
。
默认情况下,Redux动作创建者返回的普通对象如下:
dispatch
使用Redux Thunk,动作创建者实际上可以返回函数。返回函数的函数称为“ thunk”,因此称为Redux Thunk。
const returnsAnObject = () => ({
type: 'MY_ACTION'
payload: ...,
meta: ....
})
在Redux Thunk的特定情况下,您返回const returnsAFunction = (dispatch) => dispatch({
type: 'MY_ACTION'
payload: ...,
meta: ....
})
函数。 Redux Thunk使您可以通过将dispatch
作为参数提供给动作创建者来返回。
但是我得到了
dispatch
让我们打开包装。我们知道-由于Redux Thunk,您可以使用action:undefined
将多个动作链接在一起。但是,正如您在已编辑问题中提到的那样,您仍然会收到“普通对象”错误。
dispatch
这是因为您通过Promise对象而不是普通对象调用了Error: Actions must be plain objects. Use custom middleware for async actions.
at dispatch (redux.js:200)
at redux-logger.js:1
。
dispatch
要解决此问题,只需修改第二个调度以使用普通对象即可:
const visitLocationAction = (characterId, location) => {
return (dispatch) => {
return dispatch(visitLocation(characterId, location))
// Yes, it is correct to call dispatch here
// However, `dispatch` accepts plain objects, not Promise objects
.then(() => dispatch(fetchSomething()));
};
};
答案 1 :(得分:0)
如redux-promise-middleware的文档中所述,中间件可以与Redux Thunk结合使用以链接动作创建者。
因此,您可以将操作写为:
e
或使用异步/等待
const secondAction = (data) => ({
type: 'SECOND',
payload: {...},
})
const thirdAction = (data) => ({
type: 'THIRD',
payload: {...},
})
const firstAction = () => {
return (dispatch) => {
return visitLocation(characterId, location)
.then((data) => dispatch(secondAction(data)))
.then((data) => dispatch(thirdAction(data)))
}
}
然后按照您提到的方式使用它:
const secondAction = (data) => ({
type: 'SECOND',
payload: {...},
})
const thirdAction = (data) => ({
type: 'THIRD',
payload: {...},
})
const firstAction = async () => {
return (dispatch) => {
const data = await visitLocation(characterId, location));
dispatch(secondAction(data))
dispatch(thirdAction(data))
}
}