由于 redux thunk 异步调用动作创建者返回的函数,我如何确保在调用动作创建者之后 redux 在继续之前已经实际调度了动作?
我需要在对服务器的每个 POST 请求之前获取 CSRF 令牌,并且对于这两个过程都有相应的操作。
问题是,如果我连续调用这些动作创建者,POST 动作由于某种原因在 CSRF 动作被调度之前被调度。我想将这些问题分开,所以我不想合并这些操作。
如何将动作创建者调用代码与调度这些动作的 redux thunk 同步?
由于 redux thunk 异步调用动作创建者返回的函数,我如何确保在调用动作创建者之后 redux 在继续之前已经实际调度了动作?
我需要在对服务器的每个 POST 请求之前获取 CSRF 令牌,并且对于这两个过程都有相应的操作。
问题是,如果我连续调用这些动作创建者,POST 动作由于某种原因在 CSRF 动作被调度之前被调度。我想将这些问题分开,所以我不想合并这些操作。
如何将动作创建者调用代码与调度这些动作的 redux thunk 同步?
您可以将 thunk action creator 作为 Promise,使控制异步作业更容易。
export function createXHRAction(xhrType, dispatch, options) {
// you can customize createXHRAction here with options parameter.
dispatch({ type: xhrType, data: { fetching: true, data: [] });
return new Promise( (resolve, reject) => {
fetch(options.url, { ... })
.then( (response) => {
// to getting server response, you must use .json() method and this is promise object
let parseJSONPromise = response.json();
if(response.status >= 200 && response.status < 300) {
parseJSONPromise.then( (result) => {
dispatch({ type: xhrType, data: { fetching: false, data: result.data });
resolve(result.data);
});
return parseJSONPromise; // make possible to use then where calling this
}
else {
return parseJSONPromise.then( res => {
reject({ message: res.error.message });
});
}
})
.catch( (error) => {
// handles common XHR error here
});
});
}
现在您可以轻松地创建新的 XHR 操作,如下所示:
import { createXHRAction } from './actions';
export function getUser(id) {
return (dispatch) => {
return createXHRAction('user', dispatch, {
method: 'get',
url: `/user/${id}`
});
};
}
现在您可以使用同步的 thunk 操作:
import { dispatch } from './store';
import { getUser } from './action/user';
class SomeComponent extends React.Component {
...
loadData(id) {
// from here, store's state should be { fetching: true, data: [] }
dispatch(getUser(id))
.then( (userData) => {
// now from here, you can get the value from parameter or you can get it from store or component props if super component passing it by redux provider.
// store state should be { fetching: false: data [..., ...] }
// do something with received data
})
.catch( (error) => {
}));
}
}
在开始 POST 请求之前,您需要等待 CSRF-token 请求完成。
我认为将所有代码包装到动作创建器中会更好
function postAction(data) {
fetchToken().then((token) => {
//you have got token here and can use it for the POST-request.
doPost(data, token).then(() => {
//dispatch success action if you need so
})
})
}