# 状态管理
软件工程的本质即是管理复杂度。
# 什么是状态?
所谓状态,指的是与视图对应的数据,跟展示无关的东西就不算状态。
随着 JavaScript 单页应用开发日趋复杂,JavaScript 需要管理比任何时候都要多的 state (状态)。 这些 state 可能包括服务器响应、缓存数据、本地生成尚未持久化到服务器的数据,也包括 UI 状态,如激活的路由,被选中的标签,是否显示加载动效或者分页器等等。
状态,我们可以将其分为两种类型:Domain data 和 UI state。
# Domain data
Domain data非常好理解,他们直接来源于服务端对领域模型的抽象,比如user、product。它们可能被应用的多个地方用到,比如当前user包含的权限信息所有涉及鉴权的地方都需要。
通常,前端对Domain data最大的管理需求是和服务端保持同步,不会有频繁和复杂的变更——如果有的话请考虑合并批处理和转移复杂度到服务端。
# UI state
决定当前UI如何展示的状态,比如一个弹窗的开闭,下拉菜单是否打开。
和Domain data的简单、稳定不同,UI state是多变,不稳定的——不同的页面有不同、甚至相似但又细微不同的展现和交互。
UI state多变、不稳定,但它仍然是需要被复用的。小到弹窗的开闭,大到表单的管理。
# 什么是状态管理
状态决定视图(state => view) 。
现在的前端开发中,对于状态的管理是重中之重。
一个较大的项目中,会涉及到很多数据,有的是纯前端的(UI state),也有来自后端(Domain data)的,随着 View 层交互行为的驱动,整个项目中的数据需要涉及到大量的数据变更,这种变更会十分复杂,以至于我们无法追踪状态的源头,这个时候,就需要采用一些方案,来管理这些数据状态,所谓的 状态管理,管理的是从视图层事件源到数据变迁的映射过程。
# Flux思想
在 Web 应用开发中,AngularJS 扮演了重要角色。然而 AngularJS 数据和视图的双向绑定基于脏检测的机制,在性能上存在短板,任何数据的变更都会重绘整个视图。但是,由状态反应视图、自动更新页面的思想是先进的,为了解决性能上的问题,Facebook 的工程师们提出了 Virtual DOM 的思想。将 DOM 放到内存中,state 发生变化的时候,根据 state 生成新的 Virtual DOM,再将它和之前的 Virtual DOM 通过一个 diff 算法进行对比,将被改变的内容在浏览器中渲染,避免了 JS 引擎频繁调用渲染引擎的 DOM 操作接口,充分利用了 JS 引擎的性能。有了 Virtual DOM 的支持,React 也诞生了。
有了 React,state => view的思想也就有了很好的实践,但反过来呢,怎么在 view 中合理地修改 state 成为了一个新的问题,为此,Facebook 提出了 Flux 思想。
# Flux是什么?
Flux是一种架构思想,用于构建Web应用时,规范数据在应用中的流动。
Flux 的核心思想就是数据和逻辑永远单向流动。
Flux架构思想是单向数据流,将之前放到组件中各种修改数据层代码都收归一处,统一管理。组件需要修改数据层的话需要去触发预先定义好的指定dispatcher,然后dispatcher将action应用到model上,实现数据层的修改。然后数据层的修改会应用到视图上,形成一个单向数据流。
打个比方,就像图书馆的管理,原来是开放的,所有人都可以随意进出书库借书还书,如果人数不多,这种方式可以减少流程,增加效率,一旦人数变多就势必造成混乱。Flux就如同给这个图书馆加上了一个管理员,所有借书还书的行为都需要委托给管理员去做,管理员会规范对书库的操作行为,也会记录每个人的操作,减少混乱的现象。
# 主要 Flux 实现
# Redux
# MobX
简单、可扩展的状态管理
MobX是一个功能强大,上手非常容易的状态管理工具。
类型 | 地址 |
---|---|
中文文档 | https://cn.mobx.js.org/ |
# Vuex
Vue 的状态管理方法 Vuex 就是依照 Flux 的“单向数据流”理念,单向数据流示意图,如下:
← React项目目录结构 Redux介绍 →