码迷,mamicode.com
首页 > 其他好文 > 详细

[Redux] Colocating Selectors with Reducers

时间:2016-06-06 21:55:42      阅读:205      评论:0      收藏:0      [点我收藏+]

标签:

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!