zoukankan      html  css  js  c++  java
  • [Redux] Colocating Selectors with Reducers

    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;
  • 相关阅读:
    XML学习教程
    JSON 的含义?
    局域网共享问题全方位解决
    VMware虚拟化培训手册
    信息化建设中的IT规划精要
    洛谷1265 公路修建
    洛谷1144 最短路计数
    NOI题库05 派
    NOI题库7624 山区建小学(162:Post Office / IOI2000 POST OFFICE [input] )
    vijosP1014 旅行商简化版
  • 原文地址:https://www.cnblogs.com/Answer1215/p/5565084.html
Copyright © 2011-2022 走看看