总览
1.Reducers Must Be Pure Functions:(必须保证reducer函数是纯函数)
4.redux中数据的流动
这是为了保证状态的可重现。
纯函数具备以下特点:
1.相同的输出会有相同的结果,所以函数内不能使用random,time等具备随机性质的函数
2.没有任何的副作用
在这里需要注意的是,在JS中,所有传入函数的非原始类型都会以引用形式传递。
/*
原始类型 封装类
boolean Boolean
char Character
byte Byte
short Short
int Integer
long Long
float Float
double Double
原始类型之外类型通常被称为引用类型。
int i=1;//原始类型
integer i=new Integer(1)//引用类型
请注意,引用类型对象的地址的不是对象本身,而是一个对象引用。
*/
在js中,所有传入函数中的非原始类型都会以引用形式传递,如果你传入了某个对象,在函数中改变了他的值,那么在函数外该对象的属性也会随之改变,而对于原始类型来说,因为原始类型的值是不可改变的,每一次改变它的值相当于重新生成一个变量,在函数体改变的原始类型的变量并不会影响到函数体外的变量。
而对象属性的变化便是所谓的副作用,如果你没有拿到传入某个函数中的对象的全部操作记录你也就无法知道该函数的真实返回值。这让整个函数变得不可控也不确定。
Reducer应该返回全新的对象。譬如我们需要添加某个Reducer来处理
ADD_CHAT
事件。
const ACTION = 'ACTION::MY_ACTION'; const defaultState = { myRedux:{ myAction:"no" } }; const chatReducer = (state = defaultState, action = {}) => { const { type } = action; switch (type) { case ACTION: return Object.assign({}, state, { myAction:"doIt" }); default: return state; } };
Use Constants for Action Type:使用常量描述Action类型
我们希望可以方便的追踪和理解每一个Action,所以在Action的命名上我们建议启用更具代表性的命名,比如Play::GO_Fishing,这样我们在调试的时候就可以更直观的看到到底发生了什么,另外建议把所有Action声明都归类并注释在Reducer文件的首部。
使用Action Creators来将Action和Dispatch分离开来
我们都知道action是store的唯一数据来源
下面是一个简单的action creator
function addTodo(text) {
return {
type: ADD_TODO,
text
}
}
在 Redux 中的 action 创建函数只是简单的返回一个 action,这样会使action creator更加容易测试和移植。
Redux 中只需把 action 创建函数的结果传给 dispatch()
方法即可发起一次 dispatch 过程。
dispatch(addTodo(text))
或者创建一个
被绑定的 action 创建函数
来自动 dispatch:
const boundAddTodo = (text) => dispatch(addTodo(text))
const boundCompleteTodo = (index) => dispatch(completeTodo(index))
然后直接调用它们:
boundAddTodo(text);
boundCompleteTodo(index);
redux中数据的流动
严格的单向数据流是 Redux 架构的设计核心。
我们先来复习一下官方给出的redux三大原则
1.单一数据源:整个应用的state 被储存在一棵 object tree 中,并且这个 object tree 只存在于唯一一个store 中。
2.state是只读的:唯一改变state的方法是触发action
3.使用纯函数来执行修改:reducer是用来描述action改变state tree
Redux 应用中数据的生命周期遵循下面 4 个步骤:
1.调用store.dispatch(action);
2.Redux store 调用传入的 reducer 函数。
3.根 reducer 应该把多个子 reducer 输出合并成一个单一的 state 树。
Redux 原生提供combineReducers()辅助函数,来把根 reducer 拆分成多个函数,用于分别处理 state 树的一个分支。
function todos(state = [], action) {
// 省略处理逻辑...
return nextState;
}
function visibleTodoFilter(state = 'SHOW_ALL', action) {
// 省略处理逻辑...
return nextState;
}
let todoApp = combineReducers({
todos,
visibleTodoFilter
})
当你触发 action 后,
combineReducers
返回的
todoApp
会负责调用两个 reducer:
let nextTodos = todos(state.todos, action);
let nextVisibleTodoFilter = visibleTodoFilter(state.visibleTodoFilter, action);
然后会把两个结果集合并成一个 state 树:
return {
todos: nextTodos,
visibleTodoFilter: nextVisibleTodoFilter
};
4.
Redux store 保存了根 reducer 返回的完整 state 树。