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!");

[Redux] Reducer Composition with Arrays的更多相关文章

  1. [Redux] Reducer Composition with combineReducers()

    Previous, we do composition with objects: const todoApp = (state = {}, action) => { return { todo ...

  2. redux reducer笔记

    踩坑一,reducer过于抽象 reducer写得没那么抽象也不会有人怪你的.^_^ reducer其实只有一个,由不同的reducer composition出来的.所以, reducer的父作用域 ...

  3. Redux生态系统

    生态系统 Redux 是一个体小精悍的库,但它相关的内容和 API 都是精挑细选的,足以衍生出丰富的工具集和可扩展的生态系统. 如果需要关于 Redux 所有内容的列表,推荐移步至 Awesome R ...

  4. react+redux教程(四)undo、devtools、router

    上节课,我们介绍了一些es6的新语法:react+redux教程(三)reduce().filter().map().some().every()....展开属性 今天我们通过解读redux-undo ...

  5. [React Testing] Redux Reducers

    Sometimes we want to test our Redux reducers to make sure they work as expected. In this lesson we w ...

  6. 深入Redux架构

    关于redux 之前写了一篇通过一个demo了解Redux,但对于redux的核心方法没有进行深入剖析,在此重新总结学习,完整的代码看这里.(参考了React 技术栈系列教程) 什么情况需要用redu ...

  7. redux入门指南

    前言:大概一个月没有写博客了,这两天正好是周末,就写点东西来梳理下之前几个月的所写与所得; 大概两个月前,学习了一下 redux ,还是一点难度的,花了我一天的时间来搞明白他, 但是都没怎么记录,今天 ...

  8. redux (一)

    redux 是一个状态管理的库. redux认为页面所有的变化,都是基于状态的改变触发的,所以我们维护一个应用的时候,都是在维护这些状态.而 redux 就是为了维护状态而生的. API create ...

  9. React从入门到放弃之前奏(3):Redux简介

    安装 npm i -S redux react-redux redux-devtools 概念 在redux中分为3个对象:Action.Reducer.Store Action 对行为(如用户行为) ...

随机推荐

  1. asp.net用Zxing库实现条形码输出的具体实现

    首先要在项目中添加zxing.dll引用(zxing.dll下载地址http://www.jb51.net/dll/zxing.dll.html) 其次就是建立aspx文件,在后台中代码如下 复制代码 ...

  2. Xcode7 通过 Single View Application 得到一个 Empty Application 工程

    方法: 创建一个 Empty Application 工程 下面还是详细的说一下通过一个 Single View Application 工程得到一个 Empty Application 工程的方法: ...

  3. 加入强调语气,使用<strong>和<em>标签

    有了段落又有了标题,现在如果想在一段话中特别强调某几个文字,这时候就可以用到<em>或<strong>标签. 但两者在强调的语气上有区别:<em> 表示强调,< ...

  4. js 实现win7任务栏拖动效果

    前言 在某个时刻, 我认识了一个朋友. 此人在我的教唆下, 踏上了js的不归路. 前天他问我, Win7任务栏拖动效果怎么实现. 我随口就跟他说, 这简单的一逼. 在我一晚上的折腾之后, 一份潦草的代 ...

  5. Android单位度量

    px(像素):屏幕上的点. in(英寸):长度单位.mm(毫米):长度单位.pt(磅):1/72英寸.dp(与密度无关的像素):一种基于屏幕密度的抽象单位.在每英寸160点的显示器上,1dp = 1p ...

  6. backbone学习笔记(一)

    因为工作的需要,从今天起对backbone的学习过程做下记录. 学习计划: 1.1周看基本知识(2014/1/18-2014/1/25) 2.基本知识总结(2014/1/26) 3.半周按教程写hel ...

  7. 模块化的JavaScript开发的优势在哪里

    如今模块化的 JavaScript 的开发越来越火热,无论是模块加载器还是优秀的 JavaScript 模块,都是层出不穷.既然这么火,肯定是有存在的理由,肯定是解决了某些实际问题.很多没接触过模块化 ...

  8. spring 入门笔记(一)

    最近学习spring 通过笔记形式加深自己对spring的理解,也希望能跟各位入门者分享和讨论. 一.下载spring 下载spring也费了不少功夫,目前还没从spring官网找到下载入口,我从下面 ...

  9. ThinkInJava4读书笔记之第七章隐藏实施过程

    第7章 多形性 上溯造型:将一个对象作为它自己的类型使用,或者作为它的基础类型的一个对象使用.取得一个对象句柄,并将其作为基础类型句柄使用. 方法调用的绑定:将一个方法调用同一个方法主体连接到一起就称 ...

  10. 如何去除 ckeditor 上传图片后在原码中留下的 style="width: 100%;height:100px"之类的代码呢?

    ckeditor编辑器在上传图片的时候,会神奇的加上一段诡异的代码: 这导致上传的小图也是被拉伸到100%,我根本就没有定义它,找来找去也找不到element.style,原来这是在system.cs ...