我如何使用 Redux Promise 中间件链接操作?
How do I chain actions with Redux Promise Middleware?
我对 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
方法,因此我对减速器的操作不是 "binding"。
教程提到我应该调用 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
如 redux-promise-middleware, The middleware can be combined with Redux Thunk 链接动作创建者的文档中所述。
所以你可以这样写你的动作:
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)))
}
}
或使用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))
}
}
然后像你提到的那样使用它:
const mapDispatchToProps = dispatch => (
bindActionCreators({ firstAction }, dispatch)
);
Tutorials mention I should call dispatch(secondAction())
but I do not have dispatch available in my action creators.
我先回答你这部分问题。正如第一个答案中提到的,您需要 Redux Thunk,一个中间件,才能在您的 action creators 中使用 dispatch
。
默认情况下,Redux action creators return 像这样的普通对象:
const returnsAnObject = () => ({
type: 'MY_ACTION'
payload: ...,
meta: ....
})
借助 Redux Thunk,动作创建者基本上可以 return 发挥作用。 return 函数的函数称为 "thunk",Redux Thunk 的名称由此而来。
const returnsAFunction = (dispatch) => dispatch({
type: 'MY_ACTION'
payload: ...,
meta: ....
})
在 Redux Thunk 的特定情况下,您 return dispatch
函数。 Redux Thunk 使您能够 return dispatch
通过将其作为参数提供给您的操作创建者。
But I got action:undefined
让我们打开包装。我们知道——感谢 Redux Thunk——你可以使用 dispatch
将多个动作链接在一起。但是,正如您在编辑后的问题中提到的那样,您仍然会收到 "plain object" 错误。
Error: Actions must be plain objects. Use custom middleware for async actions.
at dispatch (redux.js:200)
at redux-logger.js:1
这是因为您调用 dispatch
时使用的是 Promise 对象,而不是普通对象。
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()));
};
};
要解决此问题,只需修改您的第二个分派以使用普通对象:
const visitLocationAction = (characterId, location) => {
return (dispatch) => {
return dispatch(visitLocation(characterId, location))
.then(() => dispatch({
type: 'VISIT_LOCATION_SECOND_TIME'
payload: fetchSomething()
}));
};
};
我对 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
:
const mapDispatchToProps = dispatch => (
bindActionCreators({ visitLocation }, dispatch)
);
这有效!但是,我想在 visitLocation
完成并完成后派发另一个动作。我不能调用 Promise.then()
因为它没有提供 dispatch
方法,因此我对减速器的操作不是 "binding"。
教程提到我应该调用 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
如 redux-promise-middleware, The middleware can be combined with Redux Thunk 链接动作创建者的文档中所述。
所以你可以这样写你的动作:
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)))
}
}
或使用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))
}
}
然后像你提到的那样使用它:
const mapDispatchToProps = dispatch => (
bindActionCreators({ firstAction }, dispatch)
);
Tutorials mention I should call
dispatch(secondAction())
but I do not have dispatch available in my action creators.
我先回答你这部分问题。正如第一个答案中提到的,您需要 Redux Thunk,一个中间件,才能在您的 action creators 中使用 dispatch
。
默认情况下,Redux action creators return 像这样的普通对象:
const returnsAnObject = () => ({
type: 'MY_ACTION'
payload: ...,
meta: ....
})
借助 Redux Thunk,动作创建者基本上可以 return 发挥作用。 return 函数的函数称为 "thunk",Redux Thunk 的名称由此而来。
const returnsAFunction = (dispatch) => dispatch({
type: 'MY_ACTION'
payload: ...,
meta: ....
})
在 Redux Thunk 的特定情况下,您 return dispatch
函数。 Redux Thunk 使您能够 return dispatch
通过将其作为参数提供给您的操作创建者。
But I got
action:undefined
让我们打开包装。我们知道——感谢 Redux Thunk——你可以使用 dispatch
将多个动作链接在一起。但是,正如您在编辑后的问题中提到的那样,您仍然会收到 "plain object" 错误。
Error: Actions must be plain objects. Use custom middleware for async actions.
at dispatch (redux.js:200)
at redux-logger.js:1
这是因为您调用 dispatch
时使用的是 Promise 对象,而不是普通对象。
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()));
};
};
要解决此问题,只需修改您的第二个分派以使用普通对象:
const visitLocationAction = (characterId, location) => {
return (dispatch) => {
return dispatch(visitLocation(characterId, location))
.then(() => dispatch({
type: 'VISIT_LOCATION_SECOND_TIME'
payload: fetchSomething()
}));
};
};