美文网首页
MobX的简单了解

MobX的简单了解

作者: any_5637 | 来源:发表于2019-10-31 20:22 被阅读0次

MobX

MobX 是一种简单、可扩展的状态管理,猪齿鱼框架就是用它进行状态管理。

简单理解

mobx修饰组件就是把这个全局的跟组件内的state做关联,全局的变了,局部的也变了,进而触发局部的render。

安装

  • 安装: npm install mobx --save;
  • React 绑定库: npm install mobx-react --save;
  • mobx相关依赖:npm i babel-plugin-transform-class-properties -D用来编译类(class)
    npm i babel-plugin-transform-decorators-legacy -D 用来编译装饰器
    npm install --save-dev @babel/plugin-proposal-decorators 装饰器

webpack.config.js 添加如下配置

  rules: [{
    test: /\.js$/,
    exclude: /node_modules/,
    use: {
      loader: 'babel-loader',
      options: {
        presets: ['@babel/preset-env','react'],
        plugins: ['transform-decorators-legacy', 'transform-class-properties']
      }
    }
  }]

在react-app项目下支持装饰器的解决方法

在根目录下面新建.babelr文件,写入:

  {
    "presets": ["@babel/preset-env"],
    "plugins": [
      ["@babel/plugin-proposal-decorators", { "legacy": true }],
      ["@babel/plugin-proposal-class-properties", { "loose": true }]
    ]
  }

常用api

  1. observable 使用:设置可观察数据:使用mobx的observable方法使定义的状态值可以被观察,
    observable 是一种让数据的变化可以被观察的方法,值可以是 JS原始数据类型、引用类型、普通对象、类实例、数组和映射。
  import { observable, autorun } from 'mobx';
  // JS原始类型(Number/String/Boolean)
  const value = observable(0);
  const number = observable(100);
  autorun(() => {
    console.log(value.get());
  }); // 当观测到的数据发生变化的时候,如果变化的值处在autorun中,那么autorun就会自动执行。
  value.set(1);
  value.set(2);
  number.set(101);  // 依次打印 0 1 2

  // 数组、对象类型
  const list = observable([1, 2, 4]);
  list.push(5) 
  console.log(list[0], list[1], list[2], list[3]) // 1 2 4 5

  const obj = observable({a: '11', b: '22'})
  obj.a = "leo";
  console.log(obj.a, obj.b) // leo 22

  // 映射(Map)类型
  const map = observable.map({ key: "value"});
  map.set("key", "new value");
  console.log(map.has('key'))  // true

@observable 使用: 使用装饰器 @observable 来将其转换成可观察的。

  @observer export default class PictureShow extends React.Component {}
  1. 响应可观察数据的变化:
  • (@)computed:监听相关状态变化时自动更新的值。
  const number = observable(10);
  const plus = computed(() => number.get() > 0);

  autorun(() => {
    console.log(plus.get());
  });

  number.set(-19); // number的值变化,触发computed,输出false
  number.set(-1); // number的值变化,因为-1<0,没有改变plus的值,没有输出
  number.set(1); // number的值变化,因为1>0, 输出true
  • autorun:修改autorun中任意一个可观察数据即可触发自动运行
    import { observable, autorun } from 'mobx'
    class Store {
        @observable str = 'leo';
        @observable num = 123;
    }

    let store = new Store()
    autorun(() => {
        console.log(`${store.str}--${store.num}`)
    })
    // leo--123

computed 与 autorun 区别:
@computed:用于响应式的产生一个可以被其他 observer 使用的值。
autorun:不产生新的值,而是达到一个效果(如:打印日志,发起网络请求等命令式的副作用),autorun 默认会执行一次,以获取哪些可观察数据被引用。autorun 的作用是在可观察数据被修改之后,自动去执行依赖可观察数据的行为。
@computed:如果一个计算值不再被观察了,MobX 可以自动地将其垃圾回收,而 autorun 中的值必须要手动清理才行。

  1. 修改可观察数据
  • action: 修改状态的行为,使用 action 的好处是能将多次修改可观察状态合并成一次,从而减少触发 autorun 或者 reaction 的次数。
  import { observable, computed, reaction, action} from 'mobx';

  class Store {
    @observable string = 'leo';
    @observable number = 123;
    @action bar(){
      this.string = 'pingan'
      this.number = 100
    }
  }
  let store = new Store()
  reaction(() => [store.string, store.number], arr => {
    console.log(arr)
  })
  store.bar() // ["pingan", 100]
  • runInAction(name?, thunk):action只能影响正在运行的函数,而无法影响当前函数调用的异步操作。
    在回调中需要使用action进行包裹,这里借用官网给出的例子:
  @action createRandomContact() {
  this.pendingRequestCount++;
  superagent
    .get('https://randomuser.me/api/')
    .set('Accept', 'application/json')
    .end(action("createRandomContact-callback", (error, results) => {
      if (error)
        console.error(error);
      else {
        const data = JSON.parse(results.text).results[0];
        const contact = new Contact(this, data.dob, data.name, data.login.username, data.picture);
        contact.addTag('random-user');
        this.contacts.push(contact);
        this.pendingRequestCount--;
      }
  }));
}

在end中触发的回调函数,被action给包裹了,action无法影响当前函数调用的异步操作,而回调函数是一个异步操作,所以必须再用一个action来包裹住它,这样程序才不会报错。
如果使用async function来处理,可以使用runInAction这个API来解决之前的问题。

  import {observable, action, useStrict, runInAction} from 'mobx';
  useStrict(true);

  class Store {
    @observable name = '';
    @action load = async () => {
      const data = await getData();
      runInAction(() => {
        this.name = data.name;
      });
    }
  }

调用load之后,runInAction可以立刻被执行。

结合react使用

  import React from 'react';
  import { observable, useStrict, action } from 'mobx';
  import { observer } from 'mobx-react';
  useStrict(true);

  class MyState {
    @observable num = 0;
    @action addNum = () => {
      this.num++;
    };
  }

  const newState = new MyState();

  @observer
  export default class App extends React.Component {

    render() {
      return (
        <div>
          <p>{newState.num}</p>
          <button onClick={newState.addNum}>+1</button>
        </div>
      )
    }
  }

这里定义了一个类MyState,包括可以被观察的num变量和action函数来改变num,实例化这个类并在组件中使用,使用@observer修饰App组件,组件中可以改变和观察num的值。

跨组件交互

在不使用状态管理的React要实现跨组件交互,通常需要我们在父组件定义state和修改state的函数,然后再通过props传给不同的组件,这样看起来逻辑简单,但在业务很复杂的情况下就会很繁琐,而Mobx可以更加简单的解决问题。

  class MyState {
    @observable num1 = 0;
    @observable num2 = 100;

    @action addNum1 = () => {
      this.num1 ++;
    };
    @action addNum2 = () => {
      this.num2 ++;
    };
    @computed get total() {
      return this.num1 + this.num2;
    }
  }

  const newState = new MyState();

  const AllNum = observer((props) => <div>num1 + num2 = {props.store.total}</div>);

  const Main = observer((props) => (
    <div>
      <p>num1 = {props.store.num1}</p>
      <p>num2 = {props.store.num2}</p>
      <div>
        <button onClick={props.store.addNum1}>num1 + 1</button>
        <button onClick={props.store.addNum2}>num2 + 1</button>
      </div>
    </div>
  ));

  @observer
  export default class App extends React.Component {

    render() {
      return (
        <div>
          <Main store={newState} />
          <AllNum  store={newState} />
        </div>
      );
    }
  }

上面的一段代码很好的解释了跨组件交互:Main和AllNum是两个不相关的组件,在MyState中存放组件共同需要的状态和函数,通过props将状态和函数传给两个子组件,子组件可以调用方法改变相应的状态的值。

相关文章

  • MobX的简单了解

    MobX MobX 是一种简单、可扩展的状态管理,猪齿鱼框架就是用它进行状态管理。 简单理解 mobx修饰组件就是...

  • 简单理解Mobx(二):使用方法

    上一节我们已经了解了为什么要使用Mobx,简单理解Mobx(一):使用目的 这节我们来看看如何引入并使用Mobx ...

  • 使用mobx

    mobx树型结构组织项目状态管理 遵循mobx定义数据存储 一个简单的mobx数据仓库: 因为使用了mobx作为状...

  • mobx-react 入门使用实例

    mobx 管理应用程序的状态 mobx实例 一、 新建应用 mobx-test,简单配置webpack 控制台,创...

  • 一分钟搞定 react-native mobx

    这里简单介绍mobx的用法 首先 要装几个第三方库npm i mobx -savenpm i mobx-react...

  • 初识 MobX + React-Native + React R

    MobX 简单、可扩展的状态管理(可观察的数据) 使用: 安装: npm install mobx --save。...

  • React MobX 开始

    MobX[https://mobx.js.org/] 用于状态管理,简单高效。本文将于 React 上介绍如何开始...

  • Mobx入门(一)

    Mobx是什么 MobX实现简单、可扩展的状态管理。 使用MobX将应用变成响应式可归纳为三部曲: 定义状态并使其...

  • 前端框架

    MobX:MobX 和 React 十分钟快速入门 MobX 是一种简单的、可扩展的、久经考验的状态管理解决方案。...

  • mobx VS Redux

    mobx api 简单,样板代码少 redux 需要注意的挺多,mobx 需要对依赖收集理解 Redux 规范 s...

网友评论

      本文标题:MobX的简单了解

      本文链接:https://www.haomeiwen.com/subject/vgizvctx.html