We will learn how to encapsulate the knowledge about the state shape in the reducer files, so that the components don’t have to rely on it.

In current VisibleTodoList.js:

import { connect } from 'react-redux';
import { withRouter } from 'react-router';
import { toggleTodo } from '../actions';
import TodoList from './TodoList'; const getVisibleTodos = (todos, filter) => {
switch (filter) {
case 'all':
return todos;
case 'completed':
return todos.filter(t => t.completed);
case 'active':
return todos.filter(t => !t.completed);
default:
throw new Error(`Unknown filter: ${filter}.`);
}
}; const mapStateToProps = (state, { params }) => ({
todos: getVisibleTodos(state.todos, params.filter || 'all'),
}); const VisibleTodoList = withRouter(connect(
mapStateToProps,
{ onTodoClick: toggleTodo }
)(TodoList)); export default VisibleTodoList;

Currently, the getVisibleTodos(state.todos), depends on state's structure.

Move getVisibleTodos to reducer file:

const todo = (state, action) => {
switch (action.type) {
case 'ADD_TODO':
return {
id: action.id,
text: action.text,
completed: false,
};
case 'TOGGLE_TODO':
if (state.id !== action.id) {
return state;
}
return {
...state,
completed: !state.completed,
};
default:
return state;
}
}; const todos = (state = [{
id: 0,
text: "ok",
completed: false
}], action) => {
switch (action.type) {
case 'ADD_TODO':
return [
...state,
todo(undefined, action),
];
case 'TOGGLE_TODO':
return state.map(t =>
todo(t, action)
);
default:
return state;
}
}; export default todos; export const getVisibleTodos = (state, filter) => {
switch (filter) {
case 'all':
return state;
case 'completed':
return state.filter(t => t.completed);
case 'active':
return state.filter(t => !t.completed);
default:
throw new Error(`Unknown filter: ${filter}.`);
}
};

Then in the RootReducer, we manage the state:

import { combineReducers } from 'redux';
import todos, * as fromTodos from './todos'; const todoApp = combineReducers({
todos
}); export default todoApp; export const getVisibleTodos = (state, filter) =>
fromTodos.getVisibleTodos(state.todos, filter);

Use it in VisibleTodoList.js:

import {connect} from 'react-redux';
import {toggleTodo} from '../actions';
import TodoList from './TodoList';
import {withRouter} from 'react-router';
import { getVisibleTodos } from '../reducers'; const mapStateToProps = (state, {params}) => {
return {
todos: getVisibleTodos(state, params.filter || 'all'), // if filter is '' then change to 'all'
};
}; const VisibleTodoList = withRouter(connect(
mapStateToProps,
{onTodoClick: toggleTodo}
)(TodoList)); export default VisibleTodoList;

[Redux] Colocating Selectors with Reducers的更多相关文章

  1. Redux之combineReducers(reducers)详解

    大家好,最近有点忙,忙什么呢?忙着学习一个新的框架Redux,那么这个框架主要是用来做什么的,这篇博客暂时不做介绍,这篇博客针对有一定Redux开发基础的人员,所以今天我讲的重点是Redux里面很重要 ...

  2. 通过一个demo了解Redux

    TodoList小demo 效果展示 项目地址 (单向)数据流 数据流是我们的行为与响应的抽象:使用数据流能帮我们明确了行为对应的响应,这和react的状态可预测的思想是不谋而合的. 常见的数据流框架 ...

  3. Redux初见

    说到redux可能我们都先知道了react,但我发现,关于react相关的学习资料很多,也有各种各样的种类,但是关于redux简单易懂的资料却比较少. 这里记录一下自己的学习理解,希望可以简洁易懂,入 ...

  4. 实例讲解react+react-router+redux

    前言 总括: 本文采用react+redux+react-router+less+es6+webpack,以实现一个简易备忘录(todolist)为例尽可能全面的讲述使用react全家桶实现一个完整应 ...

  5. Redux状态管理方法与实例

    状态管理是目前构建单页应用中不可或缺的一环,也是值得花时间学习的知识点.React官方推荐我们使用Redux来管理我们的React应用,同时也提供了Redux的文档来供我们学习,中文版地址为http: ...

  6. Redux教程3:添加倒计时

    前面的教程里面,我们搭建了一个简单红绿灯示例,通过在console输出当面的倒计时时间:由于界面上不能显示倒计时,用户体验并不良好,本节我们就添加一个简单的倒计时改善一下. 作为本系列的最后一篇文章, ...

  7. Redux教程1:环境搭建,初写Redux

    如果将React比喻成士兵的话,你的程序还需要一位将军,去管理士兵(的状态),而Redux恰好是一位好将军,简单高效: 相比起React的学习曲线,Redux的稍微平坦一些:本系列教程,将以" ...

  8. 用redux构建购物车

    很久没更新博客了,最近要用到react,再来跟大家分享一个redux案例吧. [ {"id": 1, "title": "iPad 4 Mini&qu ...

  9. [Redux] Fetching Data on Route Change

    We will learn how to fire up an async request when the route changes. A mock server data: /** /api/i ...

随机推荐

  1. Xcode:只修改 Bundle Identifier,不修改项目名

    找到 xx-Info.plist,打开 直接去修改 Bundle identifier 即可(默认后缀是项目名字).

  2. python多重继承:

    除了从一个父类继承外,Python允许从多个父类继承,称为多重继承. 多重继承的继承链就不是一棵树了,它像这样: class A(object): def __init__(self, a): pri ...

  3. 导入旧版本Android项目时的“Unable to resolve target ‘android

    在Ecplise + ATD + Android SDK的开发中,导入旧版本的Android项目时,往往会出现类似的如下错误 Error:Unable to resolve target 'andro ...

  4. hdu 4764 && 2013长春网赛题解

    一个组合游戏题. 解答: 从后面往前面推,首先n-1是必胜位,然后前面的k位是必败位,如此循环下去.所以题目就容易了! 代码: #include<cstdio> using namespa ...

  5. Android 使用XmlSerializer生成xml文件

    在Android开发中,我们时常要用到xml文件. xml作为一种数据载体,在数据传输中发挥着重要的作用,而且它可读性比较强. 下面给出在Android开发中使用XmlSerializer类生成一个简 ...

  6. mysql 连接url中useUnicode=true&characterEncoding=UTF-8 的作用

    添加的作用是:指定字符的编码.解码格式.            例如:mysql数据库用的是gbk编码,而项目数据库用的是utf-8编码.这时候如果添加了useUnicode=true&cha ...

  7. Android用户界面UI组件--AdapterView及其子类(五) Spinner和SpinnerAdapter

    Spinner就是下拉框组件,可以自定义下拉布局样式,可以使用ArrayAdapter以及SpinnerAdapter适配 在Adapter中实现SpinnerAdapter,继承BaseAdapte ...

  8. Android listview.item.clear()与listview.clear()的区别

    listview.clear()与listview.item.clear()的区别就是使用了listview.item.clear()后,listview控件中仍然保存着listviewitem项的结 ...

  9. centos挂载移动硬盘

    yum install ntfs-3g sudo mount -t ntfs-3g /dev/sdc1 /mnt/mobiledisk https://tuxera.com/opensource/nt ...

  10. C#读取json数据介绍

    //using System.Web.Script.Serialization; JavaScriptSerializer serializer = new JavaScriptSerializer( ...