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
原文:http://www.cnblogs.com/Answer1215/p/5565084.html