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;
  • 相关阅读:
    hp一體機cartridge error及carriage jam4/22
    指纹仪zkonline.ocx:access violation...4/13
    IIS6:Service Unaviable 9/27
    寶寶的成長腳印3/15
    vs2003不能调试4/8
    C++ 的复制构造函数
    导入与导出数据 大容量复制程序(bcp)
    关于SQlserver数据库的加密应用
    DataGridView使用技巧
    使用C# 向记事本窗口发送消息
  • 原文地址:https://www.cnblogs.com/Answer1215/p/5565084.html
Copyright © 2011-2022 走看看