设计思想
- Web 应用是一个状态机,视图与状态是一一对应的。
- 所有的状态,保存在一个对象里面。
三原则:
- 单一数据源:整个应用的State被存储在一个状态树中,且只存在于唯一的Store中。
- State是只读的
- 应用状态的改变通过纯函数(reducer)来完成
适用场景
场景:多交互、多数据源。
- 某个组件的状态,需要共享
- 某个状态需要在任何地方都可以拿到
- 一个组件需要改变全局状态
- 一个组件需要改变另一个组件的状态
基本概念和API
- Store保存数据的地方,整个应用只能有一个Store。
import { createStore } from 'redux';
const store = createStore(fn); - StateStore对象包含所有数据。如果想得到某个时点的数据,就要对 Store 生成快照。这种时点的数据集合,就叫做 State。
import { createStore } from 'redux';
const store = createStore(fn);
const state = store.getState();
Redux 规定, 一个 State 对应一个 View。只要 State 相同,View 就相同。你知道 State,就知道 View 是什么样,反之亦然。 - ActionState 的变化,会导致 View 的变化。但是,用户接触不到 State,只能接触到 View。所以,State 的变化必须是 View 导致的。Action 就是 View 发出的通知,表示 State 应该要发生变化了Action 是一个对象。其中的type属性是必须的,表示 Action 的名称。其他属性可以自由设置参考链接
const action = {
type: 'ADD_TODO',
payload: 'Learn Redux'
}; - Action Creator定义一个函数来生成Action,这个函数就叫做Action Creator。
const ADD_TODO = '添加 TODO';
function addTodo(text) {
return {
type: ADD_TODO,
text
}
}
const action = addTodo('Learn Redux'); - store.dispatch()
store.dispatch()
是 View 发出 Action 的唯一方法。import { createStore } from 'redux';
它接受一个Action对象作为参数,将它发送出去。
const store = createStore(fn);
store.dispatch({
type: 'ADD_TODO',
payload: 'Learn Redux'
});store.dispatch(addTodo('Learn Redux'));
- ReducerStore 收到 Action 以后,必须给出一个新的 State,这样 View 才会发生变化。这种 State 的计算过程就叫做 Reducer。Reducer 是一个函数,它接受 Action 和当前 State 作为参数,返回一个新的 State
const defaultState = 0;
const reducer = (state = defaultState, action) => {
switch (action.type) {
case 'ADD':
return state + action.payload;
default:
return state;
}
};
const state = reducer(1, {
type: 'ADD',
payload: 2
});
实际应用中,Reducer 函数不用像上面这样手动调用,store.dispatch方法会触发 Reducer 的自动执行。为此,Store 需要知道 Reducer 函数,做法就是在生成 Store 的时候,将 Reducer 传入createStore方法。import { createStore } from 'redux';
const store = createStore(reducer); - 纯函数只要是同样的输入,必定得到同样的输出。
- store.subscribe()Store 允许使用
store.subscribe
方法设置监听函数,一旦 State 发生变化,就自动执行这个函数。import { createStore } from 'redux';
显然,只要把 View 的更新函数(对于 React 项目,就是组件的render方法或setState方法)放入listen,就会实现 View 的自动渲染。解除监听 store.subscribe方法返回一个函数,调用这个函数就可以解除监听。
const store = createStore(reducer);
store.subscribe(listener);let unsubscribe = store.subscribe(() =>
console.log(store.getState())
);
unsubscribe();
Reducer 的拆分
不同的函数负责处理不同属性,最终把它们合并成一个大的 Reducer 即可。Redux 提供了一个combineReducers
方法,用于 Reducer 的拆分。你只要定义各个子 Reducer 函数,然后用这个方法,将它们合成一个大的 Reducer。总之,combineReducers()
做的就是产生一个整体的 Reducer 函数。该函数根据 State 的 key 去执行相应的子 Reducer,并将返回结果合并成一个大的 State 对象。
中间件
概念:中间件就是一个函数,对store.dispatch方法进行了改造,在发出 Action 和执行 Reducer 这两步之间,添加了其他功能
参考链接:
图解Redux数据流Redux 入门教程(一):基本用法
Redux 入门教程(二):中间件与异步操作
redux官网