function addTodo(filter) { return { type: SET_VISIBILITY_FILTER,filter } }
然后写减速器,像这样:
function todoApp(state = initialState,action) { switch (action.type) { case SET_VISIBILITY_FILTER: return Object.assign({},state,{ visibilityFilter: action.filter }); } }
然后我使用dispatch调用该操作:
store.dispatch(addTodo("Ask question on stackoverflow"));
似乎行动和减速器之间存在一对一的对应关系;该操作的唯一目的是选择减速器并为该减速器提供输入数据.
为什么我们不跳过中间人并确定与减速器和具有减速器功能的动作创建器的动作?然后dispatch将采用一个参数,一个类型为State =>的reducer / action.州:
// Action/reducer. (Parametrised state transformer,really.) const addTodo = text => state => { return Object.assign({},{ visibilityFilter: action.filter }); } // Dispatch takes as a argument the action/reducer store.dispatch(addTodo("Ask question on stackoverflow"));
您将失去序列化操作的能力,但除此之外,您似乎摆脱了样板操作创建者并更清楚地表达了操作和减速器之间的联系.如果您使用的是Typescript,您还可以对操作中的数据进行类型检查,即difficult to express otherwise.
那么我错过了采取数据行动的原因是什么?
解决方法
将在动作数组上调用 Reduce方法(这就是为什么它称为reducer).例:
import reducer from './reducer'; const actions = [ {type: 'INIT'},{type: 'SOME_ACTION',params: {...}},{type: 'RECEIVE_DATA',data: [...]},{type: 'SOME_ANOTHER_ACTION',... ]; const finalState = actions.reduce(reducer,undefined);
动作创建者是一个可以创建动作的功能.动作创建者不必仅创建一个动作.
实际上,如果你的reducer能够接收函数而不是对象 – 你的动作将是函数,它将主要用于实现,但你可以放弃Redux功能的一些好处.
在这种情况下,reducer将实现如下:
function reducer(state,action) { return action(state); }
您可以使用{type:’ACTION_NAME’}格式创建操作的原因:
> Redux DevTools期望这种格式.
>您需要存储操作序列.
> Reducer对worker进行状态转换.
> Redux生态系统中的每个人都使用这种格式.这是一种惯例.
>热重装功能(不会重新加载您存储的功能).
>您需要在服务器上按原样发送操作.
>调试优势 – 查看具有操作名称的操作堆栈.
>为reducer编写单元测试:assert.equal(finalState,expectedState).
>更多声明性代码 – 动作名称和参数是关于“做什么”而不是“如何做”(但addTodo(‘提问’)也是声明性的).
注意动作创建者和状态变化之间的耦合
只需比较两种符号:
第一:
function someActionCreator() { return { type: "ADD_TODO",text: "Ask question on stackoverflow" }; // returns object }
第二:
function someActionCreator() { return addTodo("Ask question on stackoverflow"); // returns function }
“在这两种情况下,我们都看到代码是声明性的,并且动作创建者与状态变化分离.您仍然可以重用addTodo或调度两个addTodo或使用中间件或调度compose(addTodo(‘One’),addTodo(‘Two’)).主要区别在于我们创建了Object和Function,并将其放置在状态发生变化的代码中.