MobX 4

The principle of

Reference: zhuanlan.zhihu.com/p/25585910

The most critical Mobx function is autoRun

const obj = observable({
    a: 1.b: 2}) when a listener attribute is referenced in autoRun (() = > {
    console.log(obj.a)
})

obj.b = 3 // Nothing happened
obj.a = 2 // The observe callback is triggered, and the console says: 2
Copy the code
  1. When a listener property is referenced in autoRun, it is hooked to that property, and when that property changes, the autoRun callback is executed
  2. Mobx-react with autoRun: Add an autoRun to the component via the @Observer modifier, so that when the component uses some listener attributes, the autoRun will be triggered and the autoRun will be directly rerender when a listener attribute changes

Some API Mobx

  • A response

    1. observable
    import { observable, action } from 'mobx';
    
    Observable can define properties to be observed
    // Actions can define functions that have side effects, such as changing observable values
    Copy the code

    store.js

    import { observable, action } from 'mobx';
    
    class store {
    
      @observable count = 0;
    
      @action
      addCount = () = > {
        this.count ++
      }
    }
    
    export default new store()
    Copy the code

    Can also be

    
    import { observable, action } from 'mobx';
    
    class store {
    
      @observable count = 0;
    
      @action
      addCount = () = > {
        this.count ++
      }
    }
    
    export default new store()
    Copy the code

    The first one is usually used more often

    1. computed

    Observable computes properties. It recalculates only when the observable property changes

    1. autorun

    The Autorun handles side effects, triggering an Observable when its value changes

    observable(() = > console.log(this.count))
    Copy the code
  • Change the observables

    1. action

    2. Asynchronous action: bound, flow

      mobx.configure({ enforceActions: true }) // State changes outside of actions are not allowed
      
      class Store {
          @observable count = 0;
      
          @action
          fetchProjects() {
              setTimeout(() = > {
                this.count ++
              }, 0); }}Copy the code

      This. count ++ will return an error because it is not modifying the @Observable variable in the @action function

      The solution
      1. We can write the assignment outside the bound:
      mobx.configure({ enforceActions: true }) // State changes outside of actions are not allowed
      
      class Store {
          @observable count = 0;
      
          @action
          fetchProjects() {
              setTimeout(() = > {
                this.addCount(1)},0);
          }
      
          @action.bound
          addCount(num) {
            this.count += num
          }
      }
      Copy the code

      While this is neat and clear, asynchronous processes can be a bit verbose when they are complex

      1. Used outside the callback functionactionpackaging
      mobx.configure({ enforceActions: true }) // State changes outside of actions are not allowed
      
      class Store {
        @observable count = 0;
      
        @action
        fetchProjects() {
          setTimeout(
            action('Name it whatever you want.'.() = > {
              this.count
            })
            , 0);
        }
      
        @action
        fetchProjectsTwo() {
          setTimeout(() = > {
            runInAction(() = > this.count++)
          }, 0); }}Copy the code

      The runInAction is the syntactic sugar for action

      1. async / await

      Lexicographically they look like synchronous functions, and it gives the impression that @action applies to the whole function. But that’s not the case, because async/await is just syntactic sugar around promise based procedures. The result is that @Action applies only to the code block until the first await

      So in async/await, after the first await, you must use an asynchronous action

      @action
      async fetchProjects() {
        const { data } = await fetchGithubProjectsSomehow() // a method to get interface data
        runInAction(() = > this.count = data.count)
      }
      Copy the code
      1. flow
      fetchProjects = flow(function * () {  // <- note the * sign, this is a generator function!
        const { data } = yield fetchGithubProjectsSomehow() // use yield instead of await
        runInAction(() = > this.count = data.count)
      })
      Copy the code
  • Tool function

    1. toJS

    Recursively converts an (Observable) object into a javascript structure

    1. extendObservable
    extendObservable(storeName, {
        age: 353
    });
    Copy the code