MobX学习之旅

MobX学习之旅

一、MobX

MobX其实是一个比较轻便的可扩展的状态管理工具,是一个由Facebook以及一些其他团队的人共同维护的开源项目。

当应用公共状态的组件在状态发生变化的时候,会自动完成与状态相关的所有事情,例如自动更新View,自动缓存数据,自动通知server等。
例如React的体系,react + redux + react-redux + redux-saga, view层触发一个action,中间件会将这个动作进行dispatch,然后reducer执行相应的更新状态方法,使得store的状态更新。

MobX官方推荐与React搭配使用,来存储和更新应用状态,所以最好搭配mobx-react中间件使用:
原理:
1、React的render是将存储的状态转化为树状结构来渲染组件的方法;
   Mobx是用来存储和更新状态的工具;
2、React使用的方法是采用虚拟Dom来进行view视图的缓存,来减少繁琐的Dom更新
   而Mobx则通过一个虚拟的状态依赖图表来让react组件和应用状态同步化来减少不必要的状态来更新组件的

二、MobX与其他状态管理工具的区别

1、对比Redux
  conponent-->dispatch(action)-->reducer-->subscribe-->getState-->component
  对比React-Redux
  component-->actionCreator(data)-->reducer-->component
这里的reducer在MobX里都给了action,直接通过action来更改状态,不需要reducer来操作state了,也不需关注reducer纯不纯了

2、对比Vuex
component-->dispatch(action)-->mutation--(mutate)-->state-->component
vuex中提出了同步mutation和异步action,现在mobx也无需mutaiton,但借鉴了computed这个纯函数。

相比这两个工具,MobX内置了数据变化监听机制,使得在实际应用的时候一切都是那么的顺其自然。

三、MobX核心模块

MobX的数据驱动解构:
    action--(update)-->state--(update)-->computed--(trigger)-->reaction
    
MobX与decorater语法结合(注解形式@)结合起来用比较优雅,也算是MobX的一大亮点吧!

Observable

是被观察着和观察者的概念,你也可以理解为生产者和消费者的概念
@observable/Observable 方法将对象的所有属性重新克隆成新对象,并将克隆对象转变成可观察的。
@observer就是在你订阅观察的对象的地方添加注释来监听对象的更新

Observable 方法的值可以是如下类型:

1、object(原型是Object): Observable方法将该对象克隆成新对象并将属性转变成可观察的;
但是后添加的属性不会变为可观察的,需要用到set或者extendObservable;

    eg: 
    @observable car = {color: red; name: 'Infinity'}
    
    注:这也其实是extendObservable(this,{ car: {color: red; name: 'Infinity'} })的语法糖
    向对象中添加属性:
    extendObservable(car, {price: '300w'})

2、Array:Observable会创建一个类数组对象来代替真正的数组,并且支持所有的原生方法,
但是sort和reverse有所不同,这里的被观察的数组对象的这两个方法,是不会改变数组本身,而是一个拷贝的数组;

3、Es6的Map:创建一个动态建的observable映射,可以对特定项的更改做出反应等;会返回一个新的Observable Map

4、object(有自身的原型对象):这种情况需要使用observable.box(value)来管理这样的值
通过box这个箱子来存这些值,并使用.get()用来获取当前值,采用.set(newValue)来更新值。

    eg:
    const carName = observable.box('Infinity');
    console.log(carName.get());
    carName.set('ofo');

Computed

 是在定义相关的一些数据发生变化的时候自动更新的值,通过@computed来修饰使用;
 注意:computed修饰的是一个状态,状态不能重复声明,只有参与计算的值发生改变才会触发computed
 
 例如我需要对数组进行筛选:
 @observable numbersArr = [99, 80, 79, 68, 2, 43, 1, 23];

一、getter
eg:
 // 筛选数组中乘2并大于50的数
  @computed get computedNumbers() {
    return this.numbersArr.filter((item) => {
      return item * 2 > 50;
    }).join(' ');
  }

然后在组件内进行调用:
<div>{this.props.store.computedNumbers}</div>

二、setter

set computedBumbers(value) {
    this.numbersArr = [99, 80, 79, 68, 2, 43, 1, 23];
}

// set方式可以使得数据进行逆推导 将数据按照既定的方式进行复原
eg:
  @observable length = 2;
  @computed get squared() {
    return this.length * this.length;
  }
  set squared(value) {
    this.length = Math.sqrt(value);
  }

注:这与autorun还有点区别,如果有一个函数应该自动运行(例如只是为了达到某种效果/功能),但不会产生一个新的值,那就使用autorun,但是一般这种情况比较少

Action

比起官方说的“动作”,我更愿意称为是“行为”,mobx的action吸收了redux和vuex的数据处理的复杂逻辑
用来修改状态,不同于Computed

eg:
component:
sendInfo = () => {
    const username = this.name.value;
    const pwd = this.pwd.value;

    if (!username || !pwd) {
      return;
    }

    // 调接口
    this.props.testDecStore.handleGetUserInfo();
  };

store:
// 四、异步数据获取
@action handleGetUserInfo() {
    this.sendCount++;
    testDecService.getUserInfo().then((data) => {
      this.userInfo = data;
   })
}

Autorun

这个函数类似computed,是通过对状态的更新做出反应,但是不同于computed。

computed创建的函数,是有自己的观察者的,而autorun是只有它的依赖关系改变时才会重新计算,
否则它的值被认为是不相干的。正如官方所说是比较适合log打印日志,持久化更新UI的代码,而不是用来产生新的值

接收的参数:
1,对象,
2、delay: 函数延迟执行时间,例如节流去抖
3、name: 
4、onError: 用来处理reaction的错误
5、scheduler: 设置自定义调度器以决定如何调度autorun函数的重新运行

eg:
autorun(() => {
    // do something
}, {
    onError(e) {
        alert('error')
    }
})


实例:
autorun(() => {
  this.myname = `my name is ${this.firstName} ${this.lastName}`;
});

changeName = () => {
    this.firstName = `Alice${new Date().getTime()}`;
    this.lastName = `Thomas${new Date().getTime()}`;
 };

<div className="tips" >
  测试autorun
  <span className="btn-span" onClick={this.changeName}>开始</span>
  <div>{this.myname}</div>
</div>
 只要firstname和lastname发生变化都会更新dom

但是,如果仅仅想要在被观察的变量有变化的时候触发,而不是立即执行autorun,那么我们可以用到reaction了;

Reaction

Reaction是在初次数据变化后才会触发

四、Mobx-react核心概念

Observer

是mobx-react包单独提供的

Observer是用来将React组建转变成响应式的组件,内部通过mobx.autorun包装了组件的
render函数,来确保store的数据更新时来刷新组件

@observer 是observer(class ***{})的注解形式,用来观察组件,
高阶组件 @observer class Test extends React.Component{}
无状态组件 const Test = observer(() => <div>test</div>)

使用inject组件连接提供的sotres,他会使得stores可以作为组件的props调用
eg:
@inject('testStore')
@observer class Test extends React.Component{} 

Provider

Provider函数为connect函数提供store参数,本身connect函数就是用来连接视图和数据层的方法。

在跟组件外层包一层provider,使得所有的子组件默认都可以拿到state

使用:

import { Provider } from 'mobx-react';
import store from '../stores';

<Provider {...store}>
    ...
</Provider>

inject

引入数据的方式,@inject(stores); 使得数据被自动保存在组件的this.props中

componentWillReact

mobx-react新增的生命周期钩子,当组件重新render的时候会被触发,但在初始渲染前是不会被触发的

onError

mobx-react提供的错误钩子函数来收集错误

用法: 

import { onError } from 'mobx-react';
onError((error) => {
    consol.log(error);
})

五、MobX源码解读

六、MobX使用注意

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/101568.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 正则实现二代身份证号码验证详解[通俗易懂]

    正则实现二代身份证号码验证详解[通俗易懂]最近项目需要对身份证进行比较合理的筛选,并不想用到第三方接口,所以写了个方法:包括支持身份证号合法性验证,支持18位身份证号,支持地址编码、出生日期、校验位验证.基本上这样就可以了.IdCodeValid:function(code){ //身份证号合法性验证 //支持15位和18位身份证号 //支持地址编码、出生日期、校验位验证 varcity={11:”北京”,12:”…

  • RocketMQ 入门使用详解[通俗易懂]

    RocketMQ 入门使用详解[通俗易懂]RocketMQ是阿里巴巴在2012年开源的分布式消息中间件,目前已经捐赠给Apache基金会,已经于2016年11月成为 Apache 孵化项目,相信RocketMQ的未来会发挥着越来越大的作用,将有更多的开发者因此受益。 本文仅对RocketMQ的简单实用做入门性介绍,不对RocketMQ的底层原理进行深入介绍,后续文章将对RocketMQ的原理做详细介绍。

  • Vue生成二维码_vue视频软件怎么生成二维码

    Vue生成二维码_vue视频软件怎么生成二维码1.在vue中安装qrcodejs2npminstall–saveqrcodejs22.在项目中引用qrcodejs2importQRcodefrom’qrcodejs2’3.使用到项目中<viewid=”qrCode”res=”qrCodeDiv”></view>methods:{bindQRcode(){ newQRcode(this.$refs.qrCodeDiv,{ text:”https://www..

  • LaTeX学习:Texlive 2019和TeX studio的安装及使用「建议收藏」

    LaTeX学习:Texlive 2019和TeX studio的安装及使用「建议收藏」文章目录1.LaTex介绍2.Texlive2019的下载和安装(1)下载(2)安装3.TeXstudio的安装以及简单使用(1)设置中文界面(2)添加行号(3)设置编译器与编码(4)第一个简单程序4.扩展1.LaTex介绍LaTeX基于TeX,主要目的是为了方便排版。在学术界的论文,尤其是数学、计算机等学科论文都是由LaTeX编写,因为用它写数学公式非常漂亮。…

  • typescript类型定义_浅基础的类型及特点

    typescript类型定义_浅基础的类型及特点基础类型TypeScript支持与JavaScript几乎相同的数据类型,此外还提供了实用的枚举类型方便我们使用。布尔值最基本的数据类型就是简单的true/false值,在JavaScri

  • 新手到黑客的最全入门路径图(附全部学习资料下载)!

    新手到黑客的最全入门路径图(附全部学习资料下载)!点击上方“程序人生”,选择“置顶公众号”第一时间关注程序猿(媛)身边的故事01入门介绍说到黑客,大家可能觉得很神秘,其实狭义上的黑客就是去寻找网站、系统、软件等漏洞,刚入门的黑客大部分从事渗透工作,而渗透大部分属于web安全方向,就是利用漏洞来取得一些数据或达到控制,让对方程序崩溃等效果。02一些常用的名词解释挖洞的话,就相当于在程序中查找漏洞,举一个不大恰当但容易理解的比喻,就像韩非子说所的那个

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号