我一直在使用什么似乎是一个非常常见的“模块”模式工作的Redux项目,其中的行动,行动创造者和负责单个状态片的动作处理程序在一个文件中组合在一起,并且从这些文件导出的缩减器通过combineReducers合并到一个单一的根缩减器中。避免进口订单/ cirulcar相关性错误与多个减速器在Redux中监听相同的动作
我一直在使用这种模式取得了一些成功,但是当我尝试让模块监听其他模块导出的操作时,我遇到了一些非常微妙和烦人的错误。
第一次遇到问题时,出现了这样的情况:模块A从模块B导入动作,模块B从模块A导入动作,创建循环依赖关系。好的,可以理解的,我可以在这种情况下工作。
但我也遇到过,仅仅从模块B中的模块A导入动作导致该动作未定义的情况 - 我假设基于模块导入或由combineReducers消化的顺序,尽管我还没有弄清楚它是如何的(即使在rootReducer文件的模块B之前导入模块A时,它似乎也会发生)。
所以我的问题:在多个减速器中听同样的动作被认为是一个好的模式,或者是要避免的事情?这似乎是Redux的做事方式所鼓舞的,但我可能会错过一些东西。
为了给出一个人为的例子,假设我想在应用程序中保留某些操作的运行日志。所以我有一个“日志”模块,用于监听所需的操作并根据需要更新其状态片段。
假设我有一个用户模块,这开始了:
export const ADD_USER = 'ADD_USER';
export function addUser (user) {
return {
type: ADD_USER,
user: user
}
};
等
然后,如果我想记录时,添加新用户,我可能会做这样的事情:
import { ADD_USER } from './users';
const ACTION_HANDLERS = {
[ADD_USER]: (state, action) => {
return [
...state,
'Added user: ' + action.user.name
];
}
}
const initialState = []
export default function logReducer (state = initialState, action) {
const handler = ACTION_HANDLERS[action.type]
return handler ? handler(state, action) : state
}
大多数情况下此方法正常工作。但是有时候ADD_USER在导入的时候是未定义的,所以动作处理器会(悄悄地)错过这个动作。很烦人!
如果这确实是要走的路,我该如何避免这些错误?显而易见的解决方案似乎是将动作常量放在一个单独的actions.js文件中,该文件在所有模块之前导入,但似乎打败了模块化的要点。另一种选择是只写操作处理程序,如:?
ADD_USER: (state, action) => {}
在听“洋”行动,但为什么定义,并将其导出为在所有的常量
这很有道理,谢谢。我也发现了这一点,解释了Dan Abramov的观点,这对任何遇到我的问题的人都有帮助:http://stackoverflow.com/a/37116923/5059128 –