核心组件
核心组件
-
Store - an object that keeps whole the state of our application
-
Actions - plain objects representing the facts about “what happened” in our app
-
Reducers - pure functions updating the state according to actions
All this staff responds to the side of logic. Let’s look further… What’s about view? There are two types of components:
-
Container - “smart” components,which are concerned with “how things work”
-
Presentational -“dumb” components,which are concerned with “how things look”

Action
const ADD_TODO = 'ADD_TODO'
{
type: ADD_TODO,
text: 'Build my first Redux app'
}
Action Creator
function addTodo(text) {
return {
type: ADD_TODO,
text,
};
}
这样做将使
function addTodoWithDispatch(text) {
const action = {
type: ADD_TODO,
text,
};
dispatch(action);
}
不同的是,
dispatch(addTodo(text));
dispatch(completeTodo(index));
或者创建一个被绑定的
const boundAddTodo = (text) => dispatch(addTodo(text));
const boundCompleteTodo = (index) => dispatch(completeTodo(index));
然后直接调用它们:
boundAddTodo(text);
boundCompleteTodo(index);
Reducer
设计State 的结构
在
- 当前选中的任务过滤条件;
- 完整的任务列表。
通常,这个
{
visibilityFilter: 'SHOW_ALL',
todos: [
{
text: 'Consider using Redux',
completed: true,
},
{
text: 'Keep all state in a single tree',
completed: false
}
]
}
开发复杂的应用时,不可避免会有一些数据相互引用。建议你尽可能地把todosById: { id -> todo }
和 todos: array<id>
是比较好的方式,本文中为了保持示例简单没有这样处理。
Action 处理
(previousState, action) => newState;
之所以将这样的函数称之为
- 修改传入参数;
- 执行有副作用的操作,如
API 请求和路由跳转; - 调用非纯函数,如
Date.now() 或Math.random() 。
只要传入参数相同,返回计算得到的下一个
import {
ADD_TODO,
TOGGLE_TODO,
SET_VISIBILITY_FILTER,
VisibilityFilters,
} from "./actions";
// ...
function todoReducer(state = initialState, action) {
switch (action.type) {
case SET_VISIBILITY_FILTER:
return Object.assign({}, state, {
visibilityFilter: action.filter,
});
case ADD_TODO:
return Object.assign({}, state, {
todos: [
...state.todos,
{
text: action.text,
completed: false,
},
],
});
default:
return state;
}
}
不直接修改
combineReducer
const reducer = combineReducers({
a: doSomethingWithA,
b: processB,
c: c,
});
function reducer(state = {}, action) {
return {
a: doSomethingWithA(state.a, action),
b: processB(state.b, action),
c: c(state.c, action),
};
}
具体在
import { combineReducers } from "redux";
function todosReducer(state = [], action) {
// ...
}
function visibilityFilterReducer(state = SHOW_ALL, action) {
// ...
}
const todoReducer = combineReducers({
visibilityFilter: visibilityFilterReducer,
todos: todosReducer,
});
Store
- 维持应用的
state ; - 提供
getState() 方法获取state ; - 提供
dispatch(action) 方法更新state ; - 通过
subscribe(listener) 注册监听器; - 通过
subscribe(listener) 返回的函数注销监听器。
当需要拆分数据处理逻辑时,你应该使用
import { createStore } from "redux";
import todoApp from "./reducers";
let store = createStore(todoApp);
let store = createStore(todoApp, window.STATE_FROM_SERVER);
发起Actions
import {
addTodo,
toggleTodo,
setVisibilityFilter,
VisibilityFilters,
} from "./actions";
// 打印初始状态
console.log(store.getState());
// 每次 state 更新时,打印日志
// 注意 subscribe() 返回一个函数用来注销监听器
const unsubscribe = store.subscribe(() => console.log(store.getState()));
// 发起一系列 action
store.dispatch(addTodo("Learn about actions"));
store.dispatch(addTodo("Learn about reducers"));
store.dispatch(addTodo("Learn about store"));
store.dispatch(toggleTodo(0));
store.dispatch(toggleTodo(1));
store.dispatch(setVisibilityFilter(VisibilityFilters.SHOW_COMPLETED));
// 停止监听 state 更新
unsubscribe();