React--"state management tool - explanation and use of Mobx

Table of contents

Explanation and use of Mobx

Mobx environment configuration

Basic use of Mobx

Use of Mobx computed properties

The use of Mobx monitoring properties

Mobx handles asynchronous usage

Modularity of Mobx


Explanation and use of Mobx

Mobx is a centralized state management tool that can work well with React. The relationship between mobx and react is equivalent to the relationship between vuex and vue. Similar tools include redux, dva, and recoil.

Advantages of mobx : write minimal code without templates to accurately describe your intentions; rely on automatic tracking of minimum rendering optimization to easily achieve optimal rendering; portability and testing to easily achieve architectural freedom; low learning cost and object-oriented programming, TS-friendly.

The core idea of ​​mobx : anything derived from application state should be obtained automatically.

The difference between Mobx and redux : Mobx is more inclined to OOP (object-oriented programming) in writing, directly modifying a piece of data without always returning a new data; it is not a single store, it can be a store; redux defaults to JavaScript Native objects store data, while Mobx uses observable objects. The detailed comparison is as follows:

redux mobx
There is a strict workflow and a lot of template code needs to be written No template code , very concise
Data needs to be immutable The data is responsive and can directly modify the data (proxy)
Redux needs middleware to handle asynchrony mobx can handle async directly
Redux has strong constraints and is more suitable for large-scale multi-person collaborative development mobx is suitable for simple, small-scale applications

Mobx version description : After the accumulation of time, mobx has also ushered in many version iterations, and the specific version description is as follows:

Mobx4 can run on any browser that supports ES5 syntax (Object.defineProperty)

The Mobx5 version runs on any browser that supports ES6 syntax (Proxy)

Mobx4 and Mobx5 have the same api, both need to use decorator syntax

Mobx6 is the latest version. In order to maximize compatibility with standard JavaScript, the decorator syntax is abandoned by default, because the decorator syntax is only for proposals. For example, ES standardization will take a long time.

It's still the same old saying: If you want to know the cutting-edge technology, you should read the official manual: mobx official documentation

Mobx environment configuration

Mobx is an independent responsive library that can exist independently of any UI framework, but through people binding it with React , Mobx is used for responsive data modeling, and React is used as the UI view architecture to render content. Configure Mobx as follows:

Create a react project environment similar to create-react-app, and use create-react-app to initialize the react project. If you want to learn more about the construction of the react framework, it is recommended to read this article: The construction and use of React scaffolding :

npx create-react-app 项目名称

Install mobx and mobx-react or mobx-react-lite, here is a brief mention: mobx-react and mobx-react-lite are middleware connecting react and mobx, the difference between the two is: mobx-react supports classes and functions Components are relatively large in size; while mobx-react-lite only supports function components and are small in size, you can use and download them according to specific situations:

npm install mobx mobx-react-lite

Basic use of Mobx

After installing the third-party packages related to mobx, you can use mobx for state management, as follows, create a store folder under the src directory, and create a counter.jsx file under the store folder to manage the count state, as follows :

import { action, makeObservable, observable } from "mobx";

class Counter {
  constructor(){
    // 参数1:target 把谁变成响应式(可观察);参数2:指定哪些属性或方法变成可观察
    makeObservable(this,{ // 设置观察模式
      count:observable, // 设置管理状态的数据
      increment:action.bound,  // 可以设置bound属性修改this指向
      decrement:action,
      reset:action
    })
  }
  // 当前的初始化状态数据
  count = 0
  
  // 操作状态的方法
  increment(){
    this.count++
  }
  decrement(){
    this.count--
  }
  reset(){
    this.count = 0
  }
}
// eslint-disable-next-line import/no-anonymous-default-export
export default new Counter()

Just import and use it in related components that want to use count data, the process is as follows:

import React from 'react'
import { observer } from 'mobx-react-lite'
import counter from './store/counter'

function App() {
  return (
    <div>
      <h3>计数器案例</h3>
      <div>点击次数:{counter.count}</div>
      <button onClick={()=>counter.increment()}>加1</button>
      <button onClick={()=>counter.decrement()}>减1</button>
      <button onClick={()=>counter.reset()}>重置</button>
    </div>
  )
}

// 使用ovserver高阶组件函数包裹需要使用store的组件
export default observer(App)

By default, the method in the class will not bind this, and the point of this depends on how to call it. Of course, if you want to call the function without using the arrow function to call the function, you can use the bound attribute to modify the pointing problem when using makeAutoObservable:

The use of makeAutoObservable : makeAutoObservable is like an enhanced version of makeObservable. By default, it will infer all attributes. The inference rules are: all attributes become observable, all methods become action, and all computed attributes become computed (computation attributes will be discussed next). The specific use is as follows:

import { makeAutoObservable } from "mobx";

class Counter {
  constructor(){
    // 参数1:target让对象变成可观察
    // 参数2:排除属性和方法
    // 参数3:指定自动绑定this
    makeAutoObservable(this,{},{autoBind:true})
  }
  // 当前的初始化状态数据
  count = 0
  // 操作状态的方法
  increment(){
    this.count++
  }
  decrement(){
    this.count--
  }
  reset(){
    this.count = 0
  }
}
// eslint-disable-next-line import/no-anonymous-default-export
export default new Counter()

Use of Mobx computed properties

Computed can be used to derive information from other observable objects. Computed values ​​are evaluated lazily, their output is cached, and they are only recomputed when the observable object they depend on is changed.

Note : A computed property is a method, and the method must be modified with get in front of it. The computed property also needs to be specified through the makeAutoObservable method, as follows:

The use of Mobx monitoring properties

There are two main methods of Mobx monitoring attributes. Now we will explain the use of the two monitoring methods respectively, as follows:

The use of autoRun

The autoRun function takes a function as a parameter, and it should run whenever the value observed by the function changes, and when you create autoRun yourself, it will also run once, Mobx will automatically collect and subscribe to all observable properties, once A change occurs and the autorun will be executed again.

import { autorun, makeAutoObservable } from "mobx";
class Counter {
  constructor(){
    makeAutoObservable(this,{},{autoBind:true})
  }
  count = 0
  increment(){
    this.count++
  }
  decrement(){
    this.count--
  }
  reset(){
    this.count = 0
  }
}
const counter = new Counter()
// 监听数据的变化
autorun(()=>{
  console.log('counter.count',counter.count);
})
export default counter

The use of reaction

React is similar to autorun, but allows more fine-grained control over which observables to track. Unlike autorun, a reaction does not run automatically when it is initialized.

import { makeAutoObservable, reaction } from "mobx";
class Counter {
  constructor(){
    makeAutoObservable(this,{},{autoBind:true})
  }
  count = 0
  increment(){
    this.count++
  }
  decrement(){
    this.count--
  }
  reset(){
    this.count = 0
  }
}
const counter = new Counter()
// 监听数据的变化
// reaction接收两个参数,参数1:data函数,其返回值会作为第二个函数的输入;参数2:回调函数
reaction(()=> counter.count,(value,oldvalue)=>{
  console.log('count数据发生变化了',value,oldvalue);
})

export default counter

Mobx handles asynchronous usage

Asynchronous processes don't need any special handling in Mobx, because all reactions will be updated automatically no matter when they are caused, and since observable objects are mutable, it is generally safe to keep references to them during action execution , if the modification of the observable object is not in the action function, the console will report a warning (it can be turned off, but it is not recommended). What does that mean? as follows:

After adding one asynchronously, we open the console of the browser to see what results we can get, as follows:

Of course, although the console pops out a warning, it does not affect the actual effect. If you want to eliminate the warning, you can set the strict mode, as follows:

Although this can eliminate the warning, it does not conform to the specification. If you want to comply with the specification, it is recommended to use this method:

Use of runlnAction

In addition to the above methods, Mobx can also use runlnAction for asynchronous processing. RunlnAction can ensure that all steps for asynchronously updating observable objects should be marked as actions. The usage is as follows:

Modularity of Mobx

In large-scale projects, it is not possible to put all states and methods in one store. We can define multiple stores according to business modules, and then manage all stores through a root store. Generally, we will set the index file under the store folder as the root store, as follows:

// 封装统一导出的store
import { createContext, useContext } from 'react';
// 两个store文件
import counter from './counter'
import list from "./list";

// 声明一个 RootStore
class RootStore {
  counter = counter
  list = list
}
const store = new RootStore()
// 创建一个上下文对象,用于跨级组件通讯
// 如果createContext提供了默认值,不需要Provider
const Context = createContext(store)
// 自定义hook
export default function useStore(){
  return useContext(Context)
}

Summary: The syntax of decorators in Mobx5 and previous versions will not be explained here. Friends who want to know can refer to official documents or Baidu by themselves.

Guess you like

Origin blog.csdn.net/qq_53123067/article/details/129707090