修改对象返回新的对象

Reducer Composition with Arrays

一个小的reducer处理每一个元素， 然后大的reducer去调用。

Since reducers are normal JS functions, they can call other reducers to delegate & abstract away updates to the state.

Reducer composition can be applied many times. While there's a single top-level reducer managing the overall state of the app, it's encouraged to have reducers call each other as needed to manage the state tree.

Reducer Composition with Objects

To store this new information, we don't need to change the existing reducers.
We will use reducer composition to create a new reducer that calls existing reducers to manage their parts of the state, then combine the parts into a single state object.

combineReducers

By convention, the state keys should be named after the reducers that manage them.

可以用ES6语法更简洁:

const todoApp =combineReducers({
todos,
visibilityFilter
});

自己实现combineReducers

const combineReducers = reducers =>{return(state ={}, action)=>{// Reduce all the keys for reducers from `todos` and `visibilityFilter`return Object.keys(reducers).reduce((nextState, key)=>{// Call the corresponding reducer function for a given key
nextState[key]= reducers[key](
state[key],
action
);return nextState;},{}// The `reduce` on our keys gradually fills this empty object until it is returned.);};};

Example: TodoList

Adding a Todo

Toggling a Todo

Filtering Todos

Refactor

Extracting Presentational Components

Todo

TodoList

One of the downsides to having separate presentational components is that we have to move around a lot of props, including the callbacks. However, we can easily solve this problem by introducing many intermediate container components.

Extracting Container Components

FilterLink

VisibleTodoList

AddTodo

Passing Store

Explicitly via Props

Implicitly via Context

You should only use context if you're using it for dependency injection.