Schedule dispatch in reducer
我知道当您要异步分派动作时,存在类似redux thunk的解决方案。但是,最近我有以下情况:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | import {store} from"./store"; const initialState = { todos: [] } a€? function todoApp(state = initialState, action) { a€? 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; } |
您可以看到
我的问题是:在redux中如何处理这种情况?
PS。这个答案说,安排在reducer中调度是很好的(我在上面的情况),甚至可以使用中间件提供一些解决方案。但是,我在博客文章中遵循了该解决方案(请参见该答案的评论),并在博客上看到Mark Erikson(Redux的维护者)的评论,但这仍然不是正确的方法。他似乎建议针对这种情况使用redux-loop。
我的问题是在redux中处理此类情况的正确方法是什么?
除了redux-loop之外,还有其他解决方案吗?
还是我们仍然可以使用redux thunk解决这种情况?
这是一个很好的例子:
1 2 3 4 5 6 7 8 | 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并更改状态(这将在超时之前发生,因为它是同步的):
1 2 3 4 5 6 7 8 9 10 | 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)来执行。