mobx 的设计思想我总结以后,主要有如下两点:javascript
mobx 不一样于 redux 的单一数据源的统一管理,它能够有多个 store, 为了便于维护 ,每个 store 都是一个类,这样便于维护和扩展;php
同时,为了使数据能够自动更新,使用了响应式编程(异步数据流), 它使用了观察者模式和 装饰器模式,将 state 包裹成observable; 当state 有改变时(本身改变或是 action 触发), 就会相应的去更新由这个state 推导出来的 computed value 以及 reaction;(数据的更新主要由装饰器模式中的对类的修改 );vue
它的工做流大体是这样子:java
mobx 与redux 同样也是单向数据流,核心概念是 state,computed value,reaction,action 等。它们的大概功能为:react
state: 包裹为 observable 的 的数据;编程
computed values: 从当前 state 中计算出的值,相似与 vue 中的computed;redux
reactions: 是当 state 改变时须要自动发生的反作用。好比打印到控制台、网络请求、递增地更新 React 组件树以修补 DOM 等等;不会产生值,常见 api 有 autorun, reaction, observe (针对性观察新旧值)等;后端
action: 是一段能够改变状态的代码。用户事件、后端数据推送、预约事件、等等。一般使用 action 统一对 state 修改,而不是对自身修改;api
这样听可能有一点抽象, 以表格为例:在电子表格中,有值的单元格都是 observable state;公式和图标是可从数据单元格和其余公式推导出的computed value;在屏幕上绘制数据单元格、公式的输出结果就是一个 reactions;对数据单元格或公式的修改就是一次action;性能优化
这里用一个栗子介绍:
class Person { // 定义状态 [@observable] firstName = "huang"; [@observable] lastName = "yuan"; [@observable] nickName; @computed get fullName() { return this.firstName + " " + this.lastName; } @action.bound increment() { this.firstName = "zhang"; } } decorate{ } const coolGirl = new Person(); // reactions:打印日志 autorun(() => { console.log( person.nickName ? person.nickName : person.fullName ) }); const ProfileView = observer(props => { if (props.person.nickName) return <div>{props.person.nickName}</div> else return <div>{props.person.fullName}</div> }); // action setTimeout(() => coolGirl.nickName = "yuanzhendashi", 5000); setIimeout(coolGirl.increment, 1000); React.render(<ProfileView person={coolGirl} />), document.body);
这是一个很简单的栗子,展现了mobx 的基本使用,主要分为这几个步骤;
这是一个最简单的例子,展现了 Mobx 主要的代码组成:定义状态 -> 注册反应 -> 修改状态 -> 执行反应。
主要跟你们说说,在与现有的技术栈或应用结合时,Mobx 生态有哪些最佳实践和优质的库。
当与 React 结合时,使用了mobox-react 库来处理 state 变化和view 更新的绑定在用法上,主要分为四个步骤:
一、 使用Provide组件用来包裹最外层组件节点,传入 store 经过 context 传递给后代组件;
2 . 经过 @observer 将 React 组件转化成响应式组件;mobx 用 autorun 包装了组件的 render 函数以确保任何组件渲染中使用的数据变化时均可以强制刷新组件;
使用 @inject 给组件注入其须要的store,放置于 props 上;
观察并使用store 中的observable 数据
以下面代码
// 以 context 的形式传入store import { Provider } from 'mobx-react' <Provider store={coolGirl}> <ProfileView/> </Provider> // 使用状态 import * as React from 'react' import { inject, observer } from 'mobx-react' @inject('store') // 若是是以 context 传入的必需要 @inject,不然不须要。 @observer **export de**fault class ProfileView extends React.Component { render () { return ( <div> 个人姓名:{this.props.store.fullName} </div> ) } }
能够看出,使用起来很是简便;
尽量多地使用小组件;@observer 组件会追踪 render 方法中全部的可观测的值,当任何一个值变化的时候,都会从新渲染,因此组件越小,从新渲染的变化就越小。
在专用的组件中渲染列表;
晚一点使用间接引用值;使用 mobx-react 时,推荐尽量晚的使用间接引用值。 这是由于当使用 observable 间接引用值时 MobX 会自动从新渲染组件。 若是间接引用值发生在组件树的层级越深,那么须要从新渲染的组件就越少;
快的: <DisplayName person={person} /> 慢的: <DisplayName name={person.name} />
对于autorun 和reaction,每次变化的准备时间和结束时间为0.5 ~ 1ms。因此,可能不适合跟踪频繁变化的状态;
减小渲染次数: 使用 action 触发状态更新;
vi设计http://www.maiqicn.com 办公资源网站大全https://www.wode007.com
内存/mobx-state-tree
综上,使用mobx-react , 会有这些优缺点: