[Redux] Reducer Composition with Arrays

本文讲解了如何在Redux中重构Reducer,通过将创建和更新待办事项的功能从整体的待办事项Reducer中抽离出来,形成专门处理单个待办事项的Reducer。这种做法有助于简化代码并提高可维护性。

In the previous lesson we created a reducer that can handle two actions, adding a new to-do, and toggling an existing to-do. Right now, the code to update the to-do item or to create a new one is placed right inside of the to-dos reducer.

This function is hard to understand because it makes us two different concerns, how the to-do's array is updated, and how individual to-dos are updated. This is not a problem unique to Redux. Any time a function does too many things, you want to extract other functions from it, and call them so that every function only addresses a single concern.

In this case, I decided that creating and updating a to-do in response to an action is a separate operation, and needs to be handled by a separate function called to-do. As a matter of convention, I decided that it should also accept two arguments, the current trait and the action being dispatched, and it should return the next trait.

But in this case, this trait refers to the individual to-do, and not to the least of to-dos. Finally, there is no magic in Redux to make it work. We extracted the to-do reducer from the to-dos reducer, so now we need to call it for every to-do, and assemble the results into an array.

While this is not required in this particular example, I suggest that you always have the default case where you return the current trait to avoid all [inaudible 1:36] in the future. The part described in this lesson is pervasive in Redux's development, and is called reducer composition.

Different reducers specify how different parts of the trait tree are updated in response to actions. Reducers are also normal JavaScript functions, so they can call other reducers to delegate and abstract a way of handling of updates of some parts of this tree they manage.

This pattern can be applied many times, and while there is still a single top level reducer managing the state of your app, you will find it convenient to express it as many reducers call on each other, each contribution to a part of the applications trait tree.

 

let todo = (state, action) => {
  switch(action.type){
      case 'ADD_ITEM':
        return {
          text: action.text,
          id: action.id,
          completed: false
        };
    case 'TOGGLE_ITEM': 
       if(state.id !== action.id){
          return state;
        }else{
         return {
          ...state,
          completed: !state.completed  // will overwirte the state object's completed prop
        };
       }
    default:
          return state;
  }
}


let todos = (state = [], action) => {
  
  switch(action.type){
    case 'ADD_ITEM':
      return state = [
        ...state,
        todo(undefined, action)
      ];
    case 'TOGGLE_ITEM':
      return state.map( (t) => todo(t, action))
    default:
      return state;
  }
};

let testTodo_addItem = () => {
  let stateBefore = [];
  let action = {
    type: 'ADD_ITEM',
    text: 'Learn Redux',
    id: 0
  };
  let stateAfter = [
    {
      text: 'Learn Redux',
      id: 0,
      completed: false,
    }
  ];
  
  deepFreeze(stateBefore);
  deepFreeze(action);
  
  expect(
    todos(stateBefore, action)
  ).toEqual(stateAfter);
};

let testTodo_toggleItem = () => {
  let stateBefore = [
    {
      text: 'Learn Redux',
      id: 0,
      completed: false
    },
    {
      text: 'Learn Angular2',
      id: 1,
      completed: false
    }
  ];
  let action = {
    type: 'TOGGLE_ITEM',
    id: 1
  };
  
  let stateAfter = [
    {
      text: 'Learn Redux',
      id: 0,
      completed: false
    },
    {
      text: 'Learn Angular2',
      id: 1,
      completed: true
    }
  ];
  
  deepFreeze(stateBefore);
  deepFreeze(action);
  
  expect(
    todos(stateBefore, action)
  ).toEqual(stateAfter);
}

testTodo_toggleItem();

console.log("All tests passed!");

 

转载于:https://www.cnblogs.com/Answer1215/p/5011830.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值