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;
  • 相关阅读:
    iOS边练边学--tableView的批量操作
    iOS边练边学--简单的数据操作(增、删、改),左滑动删除和弹窗
    iOS边练边学--自定义非等高的cell
    iOS边练边学--自定义等高的cell
    iOS边练边学--UITableViewCell的常见属性设置
    iOS边练边学--UITableView性能优化之三种方式循环利用
    iOS边练边学--介绍布局的三种方法
    c++ 函数的函数声明
    using namespace std
    java.lang.ExceptionInInitializerError
  • 原文地址:https://www.cnblogs.com/Answer1215/p/5565084.html
Copyright © 2011-2022 走看看