专栏首页云前端用MobX管理状态(ES5实例描述)-3.常用API

用MobX管理状态(ES5实例描述)-3.常用API

MobX是一个简单有效的状态管理库,以派生(derive)的概念为核心,以观察者模式为手段,达到了修改数据自动更新界面等目的

  • 正因为其本身提供了包装react的方法,可以简洁的改善react组件,所以官网文档和几乎所有教程都以react和ES7的装饰修饰符等特性为切入点
  • 但MobX在传统的ES5环境中也能良好工作,本文尝试以此为出发点,探讨在既有的非react项目中直接引入MobX并用其整理重构老代码的方法

没有babel、webpack、JSX...那么多的套路!直接上手先,走你~

[III]. 常用API

3.1 computed

computed values指的是从状态或其他派生值中派生出来的值

  • 当依赖的值改变时,派生值也自动更新
  • 产生派生值的函数应该是无副作用的纯函数

除了上面提过的在类实例里使用 getter/setter 和 computed(), computed(expression)也可以直接用来当作一个独立的函数:

var name = mobx.observable("John");var upperCaseName = mobx.computed(() =>
   name.get().toUpperCase()
);var disposer = upperCaseName.observe(
   change => console.log(change.newValue)
);name.set("Dave");
// prints: 'DAVE'

处理派生函数中的错误:

应注意正确的报错方式是 throw new Error("err"),而非throw "err"或其他

const x = observable(3)
const y = observable(1)
const divided = computed(() => {
   if (y.get() === 0)
       throw new Error("被除数是0")
   return x.get() / y.get()
})divided.get() // returns 3y.set(0) // OK
divided.get() // 报错,此次set失败y.set(2)
divided.get() // 恢复并 Returns 1.5

3.2 autorun

autorun(debugName?, fn) 被用来对那些没有单独设置观察者的状态创建reaction函数

  • 当初始化和依赖的值改变时,相关的函数就会执行
  • autorun的返回值是一个解除观察的函数
var str = mobx.observable('are you ok');
str.observe(change=>console.log(change.oldValue, '->', change.newValue));
mobx.autorun(()=>console.log('AAA', str.get()));
str.set('i am fine!');/* 输出:
AAA are you ok
AAA i am fine!
are you ok -> i am fine!
*/
var numbers = mobx.observable([1,2,3]);
var sum = mobx.computed(() => numbers.reduce((a, b) => a + b, 0));var disposer = mobx.autorun(() => console.log(sum.get())); // prints '6'numbers.push(4); // prints '10'
disposer();
numbers.push(5); // 无输出

autorun中的错误处理:

const age = mobx.observable(10);
const dispose = mobx.autorun(() => {
   if (age.get() < 0)
       throw new Error("年龄不能为负数")
   console.log("Age", age.get())
});mobx.extras.onReactionError(
   (error, derivation)=>console.warn('global err handler: ', error)
);age.set(18);  // Logs: Age 18
age.set(-10); // 报错, 但会在全局err处理中被
age.set(5);   // Recovered, logs Age 5dispose.onError(err=>console.warn(err));age.set(-5);  // 不报错,被onError拦截

3.3 action

  • action(debugName?, fn)语法,创建一个action,用来改变状态
  • action可以用于任何改变可观察状态的方法,或有副作用的方法
  • 对于派生属性对应的setter方法,将自动被视为一个action
  • 设置mobx.useStrict(true),就可以严格限定对状态的改变只能在action中进行
  • action中的fn会被包装上mobx.untracked()mobx.transaction()mobx.extras.allowStateChanges()几个方法,从而使该action达到不被追踪、允许并集中修改状态的目的
  • 如果使用action.bound(fn)替换action(fn),则fn和目标对象绑定,this指向一直都不会变

action中的异步动作:

  • action仅对其包裹的fn生效,而由fn调度的函数则不会有效果
  • 对于一些异步方法,比如setTimeout,promise或async/await,可以将需要异步处理的部分写进runInAction(name?, fn, scope?)
  • runInAction也被用来替换过时的transaction,批量执行多个状态变更,以免触发多次事件
var obj = mobx.observable({a:1, b:2});var act = mobx.action(function(){
   setTimeout(function(){
       mobx.runInAction(function(){
           obj.a = 3;
           obj.b = 4;
       });
   }, 1000);
});act();mobx.autorun(function(){
   console.log(obj.a, obj.b);
});/* 输出:
1 2
3 4
*/

* 原创文章转载请注明出处

本文分享自微信公众号 - 云前端(fewelife),作者:lua

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2017-03-31

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 实例入门 Vue.js 单元测试

    作为一个以 文档丰富 而广为人知的前端开发框架, Vue.js 的官方文档中分别在《教程-工具-单元测试》、《Cookbook-Vue组件的单元测试》里对 Vu...

    江米小枣
  • [译] 在 GitLab 中使用 Issue 面板的 4 种方式

    原文地址:https://about.gitlab.com/2018/08/02/4-ways-to-use-gitlab-issue-boards/

    江米小枣
  • 前端动画实现总结

    SVG动画由SVG元素内部的元素属性控制,一般通过一下几个元素控制: - 用于控制动画延时 - 对属性的连续改变进行控制 - 颜色变化,但用就能控制 - 控制如...

    江米小枣
  • 数据挖掘实践指南读书笔记2

    本书涉及的源程序和数据都可以在以下网站中找到:http://guidetodatamining.com/ 这本书理论比较简单,书中错误较少,动手锻炼较多,如果每...

    公众号---志学Python
  • 阔别多年 Slax 9.2.1 发布:基于 Debian “Stretch”

    消失了很长时间的 Slax Linux 终于发布了更新。昨日,Slax Linux 的作者 Tomas Matejice 发布了 Slax Linux 9.2....

    Debian社区
  • Extjs mvc

    MVC的模式,模型(Models)和控制器(Controllers) Model模型 是字段和它们的数据的集合,例如User模型带有username和passw...

    用户1197315
  • RxJava高级进阶--lift操作符

    之前几篇文章是在为这篇文章作铺垫。关于RxJava的核心思想其实可以说就在于 lift() 。

    PhoenixZheng
  • 「R」showtext:在R图里面更简单地使用字体

    在如何修改画图使用的字体[1]这篇文章中,我介绍了一种解决R图里字体的方案——extrafont包。今天意外看到另一个解决字体问题的包,再次推荐和介绍一番。

    王诗翔呀
  • 秦俊:开放 DevOps 敏捷开发套件,助力开发者驰骋云端

    DevOps可以让人工智能(AI)、大数据(Bigdata)、云计算(Cloud)更加高效地落地,越来越多的企业和团队在践行DevOps。腾讯云DevOps产品...

    云加社区
  • 文献翻译Identification of potential cancer-related pseudogenes in lung adenocarcinoma based on ceRNA h...

    假基因最初被认为是由于在进化过程中失活基因突变而导致的非功能性基因组。然而最近有研究证明假基因远非沉默,通过体内microRNA海绵的功能调节蛋白质编码基因的表...

    用户1359560

扫码关注云+社区

领取腾讯云代金券