美文网首页
前端数据流之mobx-知识点

前端数据流之mobx-知识点

作者: MickeyMcneil | 来源:发表于2019-05-16 21:00 被阅读0次

    兼容性
    ie11及以下,mobx4;ie11以上,mobx5(es6 Proxies)
    核心思想
    源自应用状态的东西都应自动获得


    初始化
    1. create-react-app创建项目
    2. yarn add -D react-app-rewired customize-cra @babel/plugin-proposal-decorators装包
    3. config-overrides.js改配置
    const { override, addDecoratorsLegacy } = require("customize-cra")
    
    module.exports = override(
      addDecoratorsLegacy()
    )
    
    1. package.json改配置
      react-scripts改成react-app-rewired
    2. yarn start启动项目

    mobx起步 - 计数器

    安装包yarn add mobx mobx-react
    index.js

    import React, { Component }  from 'react';
    import ReactDOM from 'react-dom';
    import { observable, action} from 'mobx'
    import {observer} from 'mobx-react'
    
    // 1.初始化mobx
    class store {
      @observable num = 0
      @action.bound add () {
        this.num ++
      }
    }
    // 2.使用mobx
    @observer
    class App extends Component {
      render() {
        const { store } = this.props
        return (
          <div>
            <h1>app components</h1>
            <p>{store.num}</p>
            <button onClick={store.add}>加一呀</button>
          </div>
        );
      }
    }
    // 3. 修改容器状态
    ReactDOM.render(<App store={new store()} />, document.getElementById('root'));
    

    装饰器

    对类进行处理的函数,接收的参数就是类。

    @fn1
    @fn2(20)
    @fn3
    class TestClass {
      @readonly msg = 'hello fxd' // 只能读
    }
    function fn1(target) {
     target.foo = 'foo'
    }
    function fn2(value) {
      return function (target) {
        target.count = value
      }
    }
    function fn3(target) {
      target.prototype.name = 'fxd'
    }
    // target-目标类的prototype name-类成员名 descriptor-描述对象
    function readonly(target, name, descriptor) {
      descriptor.writable = false 
    }
    console.log(TestClass.foo)
    console.log(TestClass.count)
    console.log(new TestClass().name)
    console.log(new TestClass().msg)
    

    observable

    观察数据变化的方法

    import { observable, action, autorun} from 'mobx'
    

    在计算器案例中,render里面加上

        autorun( () => {
          console.log(store.num)
        })
    

    结果为


    因此,autorun一上来就会执行,数据变化时也会执行

    computed

    计算属性

    引入

    import { observable, action, computed} from 'mobx'
    

    计算

    class store {
      @observable num = 0
      @observable price = 0.5
      @computed get total () {
        console.log('我执行了')
        return this.price * this.num
      }
    }
    

    使用计算结果

    <p>总金额:{store.total}元</p>
    

    action

    改变store里值的方法1:直接改变

    import React, { Component }  from 'react';
    import ReactDOM from 'react-dom';
    import { observable } from 'mobx'
    import {observer} from 'mobx-react'
    
    class store {
      @observable num = 0
    }
    @observer
    class App extends Component {
      render() {
        const { store } = this.props
        // 方法1.直接改变
        setTimeout(() => {
          store.num = 22
        }, 1000);
        return (
          <div>
            <h1>app components</h1>
            <p>{store.num}</p>
          </div>
        );
      }
    }
    ReactDOM.render(<App store={new store()} />, document.getElementById('root'));
    
    

    改变store里值的方法2:使用action

    import React, { Component }  from 'react';
    import ReactDOM from 'react-dom';
    import { observable, action, configure } from 'mobx'
    import {observer} from 'mobx-react'
    
    // 配置 - 必须通过action修改值
    configure({
      enforceActions: 'observed'
    })
    class store {
      @observable num = 0
      // 写改变方法
      // 使用bound是为了让this永远指向容器的实例对象
      @action.bound change () {
        this.num = 22
      }
      }
    }
    @observer
    class App extends Component {
      render() {
        const { store } = this.props
        // 方法2.用action来改变值
        setTimeout(() => {
          store.change()
        }, 1000);
        return (
          <div>
            <h1>app components</h1>
            <p>{store.num}</p>
          </div>
        );
      }
    }
    ReactDOM.render(<App store={new store()} />, document.getElementById('root'));
    

    runInAction@change的一种替代写法
    引入

    import { observable, action, configure, runInAction } from 'mobx'
    

    修改方法

    @observer
    class App extends Component {
      render() {
        const { store } = this.props
        // runInAction来改变值
        setTimeout(() => {
          runInAction(() => {
            store.num = 33
          })
        }, 1000);
        return (
          <div>
            <h1>app components</h1>
            <p>{store.num}</p>
          </div>
        );
      }
    }
    

    异步action
    有三种修改方法

    1. 定义 acion函数,业务逻辑复杂推荐使用
    2. 直接调用acion函数,原理和1类似,麻烦,不推荐使用
    3. runInAction,业务逻辑简单时使用
    import React, { Component }  from 'react';
    import ReactDOM from 'react-dom';
    import { observable, action, configure, runInAction } from 'mobx'
    import {observer} from 'mobx-react'
    
    configure({
      enforceActions: 'observed'
    })
    class store {
      @observable num = 0
      @action.bound asyncChange () {
        setTimeout(() => {
          // 方法1.定义acion函数
          // this.changeNum()
          // 方法2.直接调用action函数
          // action('changeNum', () => {
          //   this.num = 44
          // })()
          // 方法3.runInAction
          runInAction(() => {
            this.num = 55
          })
        }, 1000);
      }
    
      @action.bound changeNum () {
        this.num = 33
      }
    }
    @observer
    class App extends Component {
      render() {
        const { store } = this.props
        store.asyncChange()
        return (
          <div>
            <h1>app components</h1>
            <p>{store.num}</p>
          </div>
        );
      }
    }
    ReactDOM.render(<App store={new store()} />, document.getElementById('root'));
    

    数据监测

    • autorun
      一上来就执行,数据改变时执行
    import React, { Component }  from 'react';
    import ReactDOM from 'react-dom';
    import { observable, action, configure, autorun } from 'mobx'
    import {observer} from 'mobx-react'
    
    configure({
      enforceActions: 'observed'
    })
    class store {
      @observable num = 0
      @action.bound changeNum () {
        this.num = 22
      }
    }
    
    @observer
    class App extends Component {
      render() {
        const { store } = this.props
        store.changeNum()
        // 数据监测
        autorun(() => {
          console.log('autorun=>', store.num)
        })
        return (
          <div>
            <h1>app components</h1>
            <p>{store.num}</p>
          </div>
        );
      }
    }
    ReactDOM.render(<App store={new store()} />, document.getElementById('root'));
    
    
    
    • when
      如果满足执行条件,一上来就执行,数据改变时执行
      只执行一次,有执行条件
    import { observable, action, configure, when } from 'mobx'
    
    
        // 数据监测
        when(
          () => {
            return store.num > 100
          },
          () => {
            console.log('when=>', store.num)
          }
        )
    
    • reaction
      只有被监测数据改变时执行,会频繁执行
    import { observable, action, configure, reaction } from 'mobx'
    
        // 数据监测
        reaction(
          () => {
            return store.num > 100
          },
          (data, reaction) => {
            if (data) {
              console.log('reaction=>', data)
              // 手动停止当前reaction的监听
              reaction.dispose()
            }
          }
        )
    

    相关文章

      网友评论

          本文标题:前端数据流之mobx-知识点

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