关于redux:Redux-理解-combineReducers

28次阅读

共计 1223 个字符,预计需要花费 4 分钟才能阅读完成。

最近在我的项目中应用 redux 时遇到一个问题:应用多个 reducer 治理状态(如 ruducerA,reducerB),当通过 action 更新数据时,以后的 reducerA 数据更新胜利,但另一个 reducerB 数据被初始化。

这个行为让我十分蛊惑,排查了很久,一度找不到下手点。代码如下:

APP.js

const rootReducer = combineReducers({
  RudecerA,
  RudecerB,
});
 
const store = createStore(rootReducer);
 
 
export default function App(props) {
  return (<Provider store={store}>
        <Router {...props} />
    </Provider>
  );
}

reducerB.js

export function ReducerB(
  state = initState,
  action,
  ) {switch (action.type) {
      case UPDATE_RECORD_DATA:
        return {...state, recordData: action.payload};
       case DELETE_RECORD_DATA:
         return {...state, recordData: initRecordData};
        default:
          return initState;
   }
}

解决办法

起初在官网文档看到对于 combineReducer 的介绍及留神点:

所有未匹配到的 action,必须把它接管到的第一个参数也就是那个 state 一成不变返回。

看到这里忽然如同找到了心愿,因为我在 reducerB 中默认返回的是 initState。 于是我试着将 initState 改为 state,问题居然真的解决了!

然而为什么 combineReducer 要求默认返回 state 呢?

诘问溯源

首先咱们应用 combineRuducer 的目标是通过切片形式来治理 state,它最终会合并所有的 state 并返回。

export function combineReducers<S>(reducers: ReducersMapObject<S, any>): Reducer<CombinedState<S>>

通过查看源码,发现 combineRudecer 次要做了以下几件事:

  • 过滤不非法的 reducer
  • 遍历所有非法的 reducer,并失去新的 state
  • 判断 state 是否更新,如果更新就返回新值,否则反之。
  • 合并所有 state,并返回。

总结

因为在平时开发中应用 switch case 时,都会给 default 赋值为 initState,避免程序出错。

而在 combineReducer 中每当发动 action 时,以后 reducer 会走到 case 中,返回冀望的后果,但另外的 reducer 没有命中条件,返回的就是初始值。

有时候因为惯性思维而写下一些难以排查的 bug,十分节约精力,在应用这些库时,应该多了解其中原理,让本人少走弯路。

正文完
 0