Redux 是 JavaScript 状态容器,提供可预测化的状态管理。react
在 Redux 中,最为核心的概念就是 action 、reducer、store 以及 state,那么具体是什么呢?编程
严格的单向数据流是 Redux 架构的设计核心。json
Redux 应用中数据的生命周期遵循下面 4 个步骤:redux
核心库:数组
1 |
react |
目录结构:promise
1 |
├─app |
不过使用过 Redux 的人会有这些痛点:难懂的 API、复杂的逻辑、过多的代码侵入。Redux 采用单一根节点、函数式编程、动做分离管理(彷佛让项目很容易管理),这些都是 Redux 过于复杂的缘由。然这里并非说 Redux 很差。基于项目自己,寻找一个最适合的框架才是优的解决方案。网络
MobX 是一个通过战火洗礼的库,它经过透明的函数响应式编程(transparently applying functional reactive programming - TFRP)使得状态管理变得简单和可扩展。数据结构
比起Redux,Mobx基于观察者模式,采用多节点管理数据,是一个很轻量、入手简单、代码耦合小的数据框架。react-router
MobX 为单向数据流,也就是动做改变状态,而状态的改变会更新全部受影响的视图。架构
它由几个部分组成:Actions、State、Computed Values、Reactions。使用 MobX 将一个应用变成响应式的可概括为如下步骤:
MobX 为现有的数据结构(如对象,数组和类实例)添加了可观察的功能。 经过使用 @observable
装饰器来给你的类属性添加注解就能够简单地完成这一切。这样改属性就变成了“被观察者”。
1 |
class Store { |
observer
函数装饰器能够用来将 React 组件转变成响应式组件。 它用 mobx.autorun
包装了组件的 render
函数以确保任何组件渲染中使用的数据变化时均可以强制刷新组件。 observer
是由单独的 mobx-react
包提供的。
1 |
@observer |
这样 Index 组件就变成了一个响应式的组件(智能组件),当“被观察者”改变时,该组件就会自动更新。
React 组件一般在新的堆栈上渲染,这使得一般很难弄清楚是什么致使组件的从新渲染。 当使用 mobx-react 时能够定义一个新的生命周期钩子函数 componentWillReact
。当组件由于它观察的数据发生了改变,它会安排从新渲染,这个时候 componentWillReact
会被触发。这使得它很容易追溯渲染并找到致使渲染的操做(action)。
inject
函数装饰器能够将 Store 数据注入到组件当中。inject
是由单独的 mobx-react
包提供的。
1 |
@inject("store") |
使用 MobX,能够定义在相关数据发生变化时自动更新的值。 经过 @computed
装饰器调用 的getter / setter 函数来进行使用。
1 |
class ItemsStore { |
当添加了一个新的 items 时,MobX 会确保 total 自动更新。
action 是任一一段能够改变状态的代码。具体实现代码以下:
1 |
class HomeStore { |
若是是在严格模式:
1 |
import { useStrict } from 'mobx'; |
那么 MobX 会强制只有在动做之中才能够修改状态。对于任何不使用动做的状态修改,MobX 都会抛出异常。
action 包装/装饰器只会影响当前运行的函数,而不会影响当前函数调度(但不是调用)的函数! 这意味着若是你有一个 setTimeout、promise 的 then 或 async 语句,而且在回调函数中某些状态改变了,这些回调函数也应该包装在 action 中。可使用 action 关键字来包装 promises 回调函数
1 |
@action |
异步 action 实现的方式还有多种,这里只列举了 action 关键子的模式
在 React 中使用 MobX 须要用到 mobx-react。
其提供了 Provider 组件用来包裹最外层组件节点,而且传入 store 传递给后代组件:
1 |
import React from 'react'; |
使用 @inject
给组件注入其须要的 store(利用 React context 机制);
经过 @observer
将 React 组件转化成响应式组件,它用 mobx.autorun 包装了组件的 render 函数以确保任何组件渲染中使用的数据变化时均可以强制刷新组件:
1 |
import React, {Component} from 'react' |
其中 @withRouter
是 router 的 参数传入到组件中。