Redux 是 JavaScript 的状态容器,本篇文章主要介绍其 Action、Reducer、Store 等基础概念。
一. Action
Action 描述将要采取什么动作,同时也可以把数据传送到 store 中。以下用 toDoList 添加事项来举例:
// Action 里面的代码
function addToDo(detail) {
const date = formatDate(); // 返回当前时间的函数
return {
type: 'add',
detail: detail, // 添加的事件的描述
createdTime: date
}
}
// Reducer 里面的代码
const toDoStore = (state = [],action) => {
switch (action.type) {
case 'add':
return [
...state,
{
isDone:false,
detail:action.detail,
createdTime:action.createdTime
}
]
}
}
上面这个例子中,只要 store 实例调用 dispatch() 方法,传入 addToDo 这个 Action , Reducer 就会根据 action 传入的数据进行响应,返回一个添加了事项的新数组。
Tips:
- Action 是一个普通对象,但是它里面必须有一个 type 字段来表示将要执行的动作(可以看到 Reducer 就是根据 Action.type 来返回数据的)。
- 除了 type 字段,Action 对象结构可以任意设置。
- Action 是一个普通对象指的是 addToDo 这个 Action 函数返回的对象,返回的对象来描述本次动作的行为。可以说 Action 函数是 Action 的创建者。
二. Reducer
调用 store.dispatch( action() ) 之后, Reducer 根据传入的 Action 指定 state 应该怎么变化并发送到 store 里面。
从上面 toDoList 添加事项的例子来看:
- toDoStore 这个 Reducer 接收两个参数,第一个参数是原来的 state (在这个例子中如果没有 state 则为 ‘[]’),第二个参数是 Action 对象。而且我们需要返回一个新的 state。
- 因为传入 Reducer 的参数已经在 Action 中确定,所以不要在 Reducer 里面修改参数或者执行有副作用的函数(API请求、调用非纯函数)等操作,以达到传入的参数确定,返回的 state 一定是确定的目的。
- 返回的 state 将会传送到 state 中去,相当于更新了 state。
三. Store
Action 描述了一个动作,Reducer 根据动作返回 state,而 Store 就是把两者联系起来的对象。
let store = createStore(toDoStore); // toDoStore 从reducer引入
// 注册监听器,并把清除监听函数保存给unSubscribe
const unSubscribe = store.subscribe(() => console.log('监听到状态改变:', store.getState()));
store.dispatch(addToDo('添加一个事项'));
从上面这个例子可以看到,store 有以下功能:
- 保持应用的 state。
- 获取 state,利用 getState() 方法。
- 更新 state,利用 dispatch(action) 方法更新。
- 注册一个监听器 subscribe 并且返回一个注销监听的函数。
store 应该是唯一的,对于不同业务逻辑的 state,需要把 state 组合起来而不是创建多个 store。
状态生命周期
根据前面三章现在来整理一下 redux 状态改变的过程:
- 第一步是 Store 调用 dispatch(action),获取动作。
- 之后 Store 把旧的 state 和 Action 对象传送给 Reducer。
- Reducer 根据 Action 对象进行响应返回新的 state。
- Store 保存 Reducer 返回的新的 state。