标签:
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