简介
Redux 是一个可预测的 JavaScript 应用状态管理容器,也可以说是一个应用数据流框架。
作用
Redux 主要是用作应用状态的管理。它抽离所有组件的状态,构造一个中心化的单独常量状态树(对象)来保存这一整个应用的状态。这棵状态树与 React 组件树一一对应,相当于对 React 组件树进行了状态化建模:

- redux可以无视组件层级;
- 对于组件系统来说,redux就是一个第三方的,全局的“变量”。
特性
- 可预测
Redux可以开发出行为稳定可预测、可运行在不同环境 (客户端、服务端和原生程序)且易于测试的应用。 - 集中管理
集中式存储和管理应用的状态,可以开发出强大的功能,如撤销/重做、 状态持久化等等。 - 可调试
Redux DevTools可以轻松追踪到应用的状态在何时、何处以及如何改变。 - 数据流清晰
Redux的架构可以记下每一次改变,借助于 “时间旅行调试”,甚至可以把完整的错误报告发送给服务器。 - 灵活
Redux可与任何UI层框架搭配使用,并且有庞大的插件生态。
学习文档
Redux 中文官网
优点
在应用中使用 Redux 有如下好处:
- 预测
始终有一个准确的数据源,就是store,对于如何将actions以及应用的其他部分和当前的状态同步可以做到绝不混乱。 - 维护
具备可预测结果的性质和严格的组织结构让代码更容易维护。 - 组织
对代码应该如何组织更加严苛,这使代码更加一致,对团队协作更加容易。 - 测试
编写可测试代码的首要准则就是编写可以仅做一件事并且独立的小函数。Redux的代码几乎全部都是这样的函数:短小、纯粹、分离。 - 服务端渲染
可以带来更好的用户体验并且有助于搜索引擎优化,尤其是对于首次渲染。仅仅是把服务端创建的store传递给客户端就可以。 - 开发者工具
开发者可以实时跟踪在应用中正在发生的一切,从actions到状态的改变。 - 社区与生态圈
存在很多支持Redux的社区,使它能够吸引更多的人来使用。
核心概念
Redux 核心概念有三个:action、store、reducer。

store
在 Redux 里面, Store 是一个仓库,整合 action 和 reducer,用来保存整个应用需要管理的数据 state 。(与vuex 的 store 意义上相似)
Redux 提供了一个 createStore 来创建 state。如下:
import { createStore } from 'redux';
// 创建 store
let store = createStore(rootReducer);
let authInfo = {username: 'admin', password: '123'};
store.dispatch(authUser(authInfo));
createStore 函数接受另一个函数作为参数,返回新生成的 Store 对象。
store 特点
- 有且仅有一个
store - 维护应用的状态,获取状态:
store.getState() - 创建
store时接收reducer作为参数:const store = createStore(reducer) - 发起状态更新时,需要分发
action:store.dispatch(action)
store.getState()
store.getState() :获取 store 中存储的值
store.dispatch(action)
store.dispatch(action):派发动作,参数是一个动作对象 { type: 'xxx', data: xxx }
store.subscribe()
store.subscribe() :Store 允许使用 store.subscribe 方法设置监听函数监听store 值的变化,一旦 State 发生变化,就自动执行这个函数。
在单个组件内监听 store 的状态变化:
// redux只维护状态,但是不会触发页面更新(不会触发组件render的调用)
// 检测redux中状态的变化,就调用render
store.subscribe(() => {
this.setState({}); // 传入空对象,只为触发组件的render方法
});
如果每个组件都需要监听 store ,则可以在 index.js 入口文件监听 store,有变化则重新渲染 app 组件。
由于
react有diff算法,如果组件没有变化,不会更新所有的组件,不会引起页面重绘重排,所以不用担心效率问题。
解除监听
store.subscribe 方法返回一个函数,调用这个函数可以解除监听。
如下:
let unsubscribe = store.subscribe(() =>
console.log(store.getState())
);
unsubscribe();
actions(动作)
Actions 就是事件,传递来自这个应用的视图层发起的一个操作(比如用户接口,内部事件比如 API 调用和表单提交),告诉 store 需要改变 state。
Actions 提交数据给 store,store 只获取来自 Actions 的信息。
Action 描述了 action 的类型以及传递给 store 的负载信息,它有两个属性:
(1) type (通常是常量):标识属性,表示 action 的名称;
(2) payload :数据属性,可选。可以带一些参数,表示本次动作携带的数据,用作 Store 变更。
如下:
{
type: LOGIN_FORM_SUBMIT,
payload: {username: 'admin', password: '123'}
}
如上所示,定义了一个名为 LOGIN_FORM_SUBMIT 的 Action,还携带了payload 的参数。
Action Creator
View 要发送多少种消息,就会有多少种 Action。在Redux 中,可以用 Action Creator 生成器来批量生成一些 Action:
function authUser(form) {
return {
type: LOGIN_FORM_SUBMIT,
payload: form
}
}
store.dispatch()
Action 不会自己主动发出变更操作 Store,在应用中需要使用 dispatch 方法来调用 actions,它专门用来发出action:
dispatch(authUser(form));
在 Redux里面,store.dispatch() 是 View 发出 Action 的唯一方法。
action 特点
- 只描述做什么;
JS对象,必须带有type属性,用于区分动作的类型;- 根据功能的不同,可以携带额外的数据,配合该数据来完成相应功能。
reducers
当 store.dispatch 发起了一个 action 之后,会到达 reducer,reducer 获得这个应用的当前状态和事件并完成,经过计算,返回一个新的 state 状态对象给 store(这使得 Redux 非常简单以及可预测)。
在函数式
JavaScript中reducer基于数组reduce方法,接收一个回调(reducer)可以从多个值中获得单个值,整数和,或者一个一系列值的累积。
如下:
function handleAuth(state, action) {
return _.assign({}, state, {
auth: action.payload
});
}
对于更多复杂的项目,推荐使用
Redux提供的combineReducers()实例。它把在这个应用中所有的reducer结合在一起成为单个索引reducer。每一个reducer负责它自己那部分应用的状态,这个状态参数和其他reducer的不一样。combineReducers()实例使文件结构更容易维护。
如下:
const rootReducer = combineReducers({
handleAuth: handleAuth,
editProfile: editProfile,
changePassword: changePassword
});
如果一个对象
(state)只改变一些值,Redux就创建一个新的对象,那些没有改变的值将会指向旧的对象而且新的值将会被创建。这对性能是极好的。为了让它更有效率可以添加Immutable.js。
reducer 特点
- 是一个纯函数,可查看之前的状态,执行一个
action并返回一个新的状态; - 接收两个参数:当前的
state和接收到的action,返回一个新的state。
纯函数的意思是说,对于相同的输入,只会有相同的输出,不会影响外部的值,也不会被外部的值所影响。



















