# 状态管理

react-redux

Redux 是 JavaScript 状态容器,提供可预测化的状态管理。

# 前端为何需要状态管理

近年来,随着单页面应用的兴起,JavaScript 需要管理比任何时候都要多的状态,或者可以说是数据,这些状态可能包括服务器响应、缓存数据、本地生成尚未持久化到服务器的数据,也包括 UI 状态,如激活的路由,被选中的标签,是否显示加载动效或者分页器等等,这些都是十年前二十年前的 web 开发没有遇到的挑战。

但是其实,无论系统如何复杂,前端页面的所要完成的事其实很简单,就是把业务的信息渲染出来,反馈给用户,并进行人机交互,返回给服务端,这是前端技术解决的核心问题

# 广义的状态管理

状态管理是一个十分广泛的概念,因为状态无处不在。服务端也有状态,Spring 等框架会管理状态,RDS 和 redis 等组件会保存数据,手机 App 也会把数据保存到手机内存里,状态管理不是什么新鲜事物

# 狭义的状态管理

现在的状态管理已经成为了前端开发技术栈的一个主题,工具库和框架都十分丰富。现在谈及状态管理,虽然概念还是很很宽泛,但是还是能收敛到几个点上。

  • 数据流的方向性管理,如 Flux
  • 系统状态的框架性工具管理,例如 Redux,Mobx
  • 组件生命周期内的状态管理,例如在 React 中使用 setState 或者 hooks
  • ...

事实上,现在前端开发谈及状态管理,其实就是指的是像 Redux 这样的东西,用单一数据流的思想指导整个系统,并把状态存储到特定的地方,在 UI 组件层通过一些选择器把需要组件取出,渲染到 UI 上

# 状态管理的好处及带来的问题

最后,总结性地回到一下为什么要做状态管理,状态管理有以下的好处

  • 能有效分离 UI 层和数据处理层
  • 帮助前端应用结构化数据
  • 有效控制状态的变化
  • 处理同步与异步
  • 实现一些日志打印,热加载,时间旅行,同构应用等功能
  • ...

# 认识 Redux

说到状态管理,那就不得不说 Redux。Redux是将整个应用的状态存储到到一个地方,称为 store。所有的数据都存在 state 中。各个组件可以派发 dispatch 行为 action 给 store,而不是直接通知其它组件。其它组件可以通过订阅 store 中的状态(state)来刷新自己的视图。没错,这就是典型的发布订阅模式。

Redux有以下几个特征:

  • 整个应用的 state 被储存在一个 object 中
  • state 是只读的,惟一改变 state 的方法就是触发 action
  • action 是一个用于描述已发生事件的普通对象,使用纯函数来执行修改
  • 为了描述 action 如何改变state ,需要编写 reducers
  • 单一数据源的设计让 React 的组件之间的通信更加方便,同时也便于状态的统一管理

# 使用 Redux

npm install --save redux
npm install --save react-redux
npm install --save-dev redux-devtools
// src/store/index.js
import { createStore } from "redux";

const INCREMENT = "INCREMENT";
const DECREMENT = "DECREMENT";
let initState = { number: 0 };

const reducer = (state = initState, action) => {
  switch (action.type) {
    case INCREMENT:
      return { number: state.number + 1 };
    case DECREMENT:
      return { number: state.number - 1 };
    default:
      return state;
  }
};
let store = createStore(reducer);
function render() {
  console.log(store.getState().number);
}
store.subscribe(render);
render();
store.dispatch({ type: INCREMENT });
store.dispatch({ type: DECREMENT });

总结一下 Redux 的用法:

  1. 定义 reducer,建立 action 改变 state 的规则
  2. createStore 创建 store
  3. subscribe 订阅函数,当 state 变化时触发
  4. dispatch 方法派发 action

# 理解 Store、State、Action

{
  todos: [{
    text: 'Eat food',
    completed: true
  }, {
    text: 'Exercise',
    completed: false
  }],
  visibilityFilter: 'SHOW_COMPLETED'
}

# 理解异步 Action、Redux中间件

# 如何组织 Action 和 Reducer

# 理解不可变数据

# 学习资料

Redux - A Predictable State Container for JS Apps (opens new window)

Redux 中文文档 (opens new window)

The deepest reason why modern JavaScript frameworks exist (opens new window)

《现代 js 框架存在的根本原因》 (opens new window)

为什么要做状态管理 (opens new window)