在减速器中调度调度

时间:2018-07-28 21:41:17

标签: javascript redux

我知道当您要异步分派操作时,存在类似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解决这种情况?

1 个答案:

答案 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)来完成。