• [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;
  • 相关阅读:
    「洛谷 NOIP 计划 2021」【学习1】降维技巧
    组合数取模 合集
    浅谈并查集
    四边形不等式优化 dp (doing)
    qbxt数学五一Day4
    qbxt五一数学Day3
    qbxt五一数学Day2
    qbxt五一数学Day1
    浅谈拉格朗日插值
    10-交换排序:冒泡排序
  • 原文地址:https://www.cnblogs.com/Answer1215/p/5565084.html
Copyright © 2020-2023  润新知