Redux 中一个 action 依赖另一个 async action 怎么办?
What should I do if an action depend on another async action in Redux?
对不起我的英语,希望你能理解我。
我使用 redux-thunk
进行异步操作。
// actionA.js
export function actionA() {
return fetch('api call')
.then((data) => ({
type: 'actionA',
data: data
}))
}
// reducer.js
export function reducer(state, action) {
...
if(action.type === 'actionA') {
return {
...,
dataA: action.data,
...
};
}
}
// actionB.js
export function actionB() {
return (dispatch, getState) => {
if(!getState().dataA) {
dispatch(actionA());
}
doSomethingWithDataA(getState().dataA);
};
}
在某些情况下,我只需要调度actionA
而不调度actionB
。但是当我调度 actionB
时,actionB
将使用 dataA
,而 dataA
是由 actionA
创建的。所以在actionB
中,我会检查Store
中是否有dataA
,如果没有,我会先调度actionA
。但是 actionA
是一个异步操作,当 actionA
完成时我无法获取。
那么如何处理这个问题呢?
这种方法可能会有所帮助,注意我将使用 fetch polyfill 来 return aysnc 请求的承诺。
function actionA(dataA) {
return {
type: 'actionA',
data: dataA
};
}
export function actionB() {
return (dispatch, getState) => {
if(!getState().dataA) {
return fetch('api call')
.then((data) => {
dispatch(actionA(data))
})
.catch((error) => {// handle error})
}
return doSomethingWithDataA(getState().dataA);
}
}
一般来说,您想在 dataA
准备就绪并且 actionB
已经发生时做某事。您可以使用 middleware
function myMiddleware() {
return store => next => action => {
const dataA = store.getState().dataA;
if(store.getState().dataA && action.type === 'actionB') {
doSomethingWithDataA(dataA);
}
};
}
那么你的actionB就变成了下面的
function lazyFetchDataA() {
return (dispatch, getState) => {
if(!getState().dataA) {
return dispatch(actionA());
} else {
return Promise.resolve();
}
}
}
export function actionB() {
return (dispatch, getState) => {
lazyFetchDataA().then(() => dispatch({type: 'actionB'}))
}
}
这看起来很难,但现在您可以在适当的地方使用少量代码来完成您的工作。
如果你提供更多信息你的doSomethingWithDataA
是什么,可能你不必做这么困难的事情,我会给出更好的答案。
对不起我的英语,希望你能理解我。
我使用 redux-thunk
进行异步操作。
// actionA.js
export function actionA() {
return fetch('api call')
.then((data) => ({
type: 'actionA',
data: data
}))
}
// reducer.js
export function reducer(state, action) {
...
if(action.type === 'actionA') {
return {
...,
dataA: action.data,
...
};
}
}
// actionB.js
export function actionB() {
return (dispatch, getState) => {
if(!getState().dataA) {
dispatch(actionA());
}
doSomethingWithDataA(getState().dataA);
};
}
在某些情况下,我只需要调度actionA
而不调度actionB
。但是当我调度 actionB
时,actionB
将使用 dataA
,而 dataA
是由 actionA
创建的。所以在actionB
中,我会检查Store
中是否有dataA
,如果没有,我会先调度actionA
。但是 actionA
是一个异步操作,当 actionA
完成时我无法获取。
那么如何处理这个问题呢?
这种方法可能会有所帮助,注意我将使用 fetch polyfill 来 return aysnc 请求的承诺。
function actionA(dataA) {
return {
type: 'actionA',
data: dataA
};
}
export function actionB() {
return (dispatch, getState) => {
if(!getState().dataA) {
return fetch('api call')
.then((data) => {
dispatch(actionA(data))
})
.catch((error) => {// handle error})
}
return doSomethingWithDataA(getState().dataA);
}
}
一般来说,您想在 dataA
准备就绪并且 actionB
已经发生时做某事。您可以使用 middleware
function myMiddleware() {
return store => next => action => {
const dataA = store.getState().dataA;
if(store.getState().dataA && action.type === 'actionB') {
doSomethingWithDataA(dataA);
}
};
}
那么你的actionB就变成了下面的
function lazyFetchDataA() {
return (dispatch, getState) => {
if(!getState().dataA) {
return dispatch(actionA());
} else {
return Promise.resolve();
}
}
}
export function actionB() {
return (dispatch, getState) => {
lazyFetchDataA().then(() => dispatch({type: 'actionB'}))
}
}
这看起来很难,但现在您可以在适当的地方使用少量代码来完成您的工作。
如果你提供更多信息你的doSomethingWithDataA
是什么,可能你不必做这么困难的事情,我会给出更好的答案。