由于redux thunk异步调用动作创建者返回的函数,在调用动作创建者之后我如何确保redux在继续之前实际调度了动作?
我需要在每次POST请求到服务器之前获取CSRF令牌,并且对于这两个过程都有相应的操作。
问题是,如果我连续调用这些动作创建者,POST动作由于某种原因在调度CSRF动作之前被调度。我想把这些问题分开,所以我不想把这些行动结合起来。
如何使用redux thunk同步动作创建者调用代码来调度这些动作?
答案 0 :(得分:6)
您可以将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) => {
}));
}
}
答案 1 :(得分:2)
在开始POST请求之前,您需要等待CSRF令牌请求完成。
我认为将所有代码包装成动作创建者
会更好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
})
})
}