[英]How do I chain actions with Redux Promise Middleware?
I am quite new to React and Redux. 我是React和Redux的新手。 I want to chain multiple API calls using redux-promise-middleware and implemented my actions as follows: 我想使用redux-promise-middleware链接多个API调用,并按如下方式实现我的操作:
locationActions.js: 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 };
I dispatch this action from my React component using mapDispatchToProps
: 我使用mapDispatchToProps
从我的React组件调度此操作:
const mapDispatchToProps = dispatch => (
bindActionCreators({ visitLocation }, dispatch)
);
This works! 这有效! However, I want to dispatch another action after visitLocation
is settled and fulfilled. 但是,我希望在visitLocation
结算和完成后发送另一个操作。 I can not call Promise.then()
because it doesn't provide the dispatch
method, therefore not "binding" my action to the reducer. 我无法调用Promise.then()
因为它不提供dispatch
方法,因此不会将我的操作“绑定”到reducer。
Tutorials mention I should call dispatch(secondAction())
but I do not have dispatch available in my action creators. 教程提到我应该调用dispatch(secondAction())
但我的动作创建者没有可用的调度。
Can someone point out to me what am I missing? 有人能指出我错过了什么吗?
Edit: 编辑:
As suggested in the first answer, I tried the following approach: 正如第一个答案所示,我尝试了以下方法:
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 };
But I got action:undefined and the following error: 但我得到了行动:未定义和以下错误:
Error: Actions must be plain objects. Use custom middleware for async actions.
at dispatch (redux.js:200)
at redux-logger.js:1
Tutorials mention I should call
dispatch(secondAction())
but I do not have dispatch available in my action creators. 教程提到我应该调用dispatch(secondAction())
但我的动作创建者没有可用的调度。
Let me answer this part of your question first. 让我先回答你问题的这一部分。 As mentioned in the first answer, you need Redux Thunk , a middleware, to use dispatch
in your action creators. 正如第一个答案中提到的,您需要Redux Thunk (一种中间件)在您的动作创建者中使用dispatch
。
By default, Redux action creators return plain objects like this: 默认情况下,Redux操作创建者返回如下的普通对象:
const returnsAnObject = () => ({
type: 'MY_ACTION'
payload: ...,
meta: ....
})
With Redux Thunk, action creators can essentially return functions. 使用Redux Thunk,动作创建者基本上可以返回功能。 A function that returns a function is called a "thunk", hence the name of Redux Thunk. 返回函数的函数称为“thunk”,因此称为Redux Thunk。
const returnsAFunction = (dispatch) => dispatch({
type: 'MY_ACTION'
payload: ...,
meta: ....
})
In the specific case of Redux Thunk, you return the dispatch
function. 在Redux Thunk的特定情况下,您将返回dispatch
功能。 Redux Thunk enables you to return dispatch
by providing it as a parameter to your action creators. Redux Thunk使您可以通过将其作为参数提供给您的操作创建者来返回dispatch
。
But I got
action:undefined
但我action:undefined
了action:undefined
Let's unpack this. 我们打开这个。 We know--thanks to Redux Thunk--you can chain multiple actions together using dispatch
. 我们知道 - 感谢Redux Thunk - 您可以使用dispatch
多个动作链接在一起。 However, as you mentioned in your edited question, you still get the "plain object" error. 但是,正如您在编辑过的问题中提到的那样,仍然会出现“普通对象”错误。
Error: Actions must be plain objects. Use custom middleware for async actions.
at dispatch (redux.js:200)
at redux-logger.js:1
This is because you called dispatch
with a Promise object, not a plain object. 这是因为您使用Promise对象调用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()));
};
};
To fix this problem, simply modify your second dispatch to use a plain object: 要解决此问题,只需修改第二个调度以使用普通对象:
const visitLocationAction = (characterId, location) => {
return (dispatch) => {
return dispatch(visitLocation(characterId, location))
.then(() => dispatch({
type: 'VISIT_LOCATION_SECOND_TIME'
payload: fetchSomething()
}));
};
};
As mentioned in the documentation for redux-promise-middleware , The middleware can be combined with Redux Thunk to chain action creators. 正如redux-promise-middleware的文档中所提到的,中间件可以与Redux Thunk结合使用,以链接动作创建者。
So you can write your action like: 所以你可以写下你的行动:
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))) } }
or use async/await 或使用async / await
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)) } }
and then use it as you mentioned: 然后按照你的提及使用它:
const mapDispatchToProps = dispatch => (
bindActionCreators({ firstAction }, dispatch)
);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.