我知道当您要异步分派操作时,存在类似redux thunk的解决方案。但是,最近我有以下情况:
import {store} from "./store";
const initialState = {
todos: []
}
function todoApp(state = initialState, action) {
if(action.type == "ACTION_A"){
// 1. do smth with state
// 2. do smth with state, and then... schedule a dispatch say using setTimeout:
setTimeout(()=>store.dispatch({type:"ACTION_B", payload:1}), 2000);
return state;
}// check other actions e.g. ACTION_B etc.
return state;
}
您可以看到ACTION_B
不是我想从其他地方发出的动作,例如说是异步动作(这样我就可以使用redux thunk了),而是{{ 1}}。
我的问题是:在redux中如何处理这种情况?
PS。这个answer表示,可以在reducer中安排调度(我在上面的情况),甚至可以使用中间件提供一些解决方案。但是,我在博客文章中遵循了该解决方案(请参阅该答案的评论),并看到Mark Erikson(Redux的维护者)在博客上的评论,认为这仍然不是正确的方法。他似乎建议针对这种情况使用redux-loop。
我的问题是在redux中处理此类情况的正确方法是什么? 除了redux-loop以外,还有其他解决方案吗?
还是我们仍然可以使用redux thunk解决这种情况?
答案 0 :(得分:2)
这是一个很好的例子:
const actionA = () = ({ dispatch, getState }) => {
dispatch(actionA1) // dispatch another action that will change the state
setTimeout(()=> {
const { data } = getState();
dispatch({type:"ACTION_B", payload: data });
}, 2000);
}
或自定义的中间件,它将安排超时,但将允许actionA继续执行reducer并更改状态(这将在超时之前发生,因为它是同步的):
const middleware = ({ dispatch, getState }) = next => action => {
if(action.type == "ACTION_A"){ //
setTimeout(()=> {
const { data } = getState();
dispatch({type:"ACTION_B", payload: data });
}, 2000);
}
next(action);
}
通常,reducer应该是纯函数,即没有诸如调度或调度动作之类的副作用。如果某个动作除了改变状态还需要做其他事情,则应该使用中间件(例如thunk)来完成。