react18【系列实用教程】moxb —— 集中状态管理 (2024最新版)

简介: react18【系列实用教程】moxb —— 集中状态管理 (2024最新版)

官方文档 https://www.mobxjs.com/

moxb 和 redux 都能用于 react 的状态管理,但 moxb 更简单,适合规模不大的应用 (规模大的应用若合理组织代码结构,也能用 moxb)

安装 moxb

npm i mobx
npm i mobx-react-lite
  • 此处安装 mobx-react-lite 仅可用于函数组件,不支持类组件
  • 若想同时支持类组件和函数组件,则需安装 mobx-react

moxb 的工作流程

moxb 的目录结构

  • 在 src 目录下创建文件夹 store
  • 在文件夹 store 中根据需要创建 js/ts 文件,比如常用的全局状态–当前登录用户,则创建 User.js 文件

moxb 的基本使用

1. 定义响应式的属性和方法

以 User.js 为例,详见注释

import { makeAutoObservable } from "mobx";

// 定义类
class User {
  // 构造函数
  constructor() {
    /** 【自动创建响应式】
     *  第1个参数:要创建为响应式的对象,此处的this即指当前类
     *  第2个参数:默认第1个参数的所有属性和方法都会添加响应式,可在此指定不添加响应式的属性和方法,如{if_Login:false},即属性if_Login无响应式
     *  第3个参数:指定自动绑定this,方便在页面使用时,绑定事件无参数时可不使用箭头函数
     */
    makeAutoObservable(this, {}, { autoBind: true });
  }

  // 属性 if_Login --- 用户是否登录
  if_Login = false;
  // 属性 info --- 用户的信息
  info = {};

  // 方法 -- 用户登录
  login(newInfo) {
    // 将属性 if_Login 的值设置为 true
    this.if_Login = true;
    // 将传入的参数赋值给属性 info
    this.info = newInfo;
  }

  // 方法 -- 用户登出
  logout() {
    // 将属性 if_Login 重置为 false
    this.if_Login = false;
    // 将属性 info 重置为 {}
    this.info = {};
  }
}

// 导出类实例
export default new User();

2. 在页面中使用

  • 需用 observer 函数包裹目标组件,这样页面才能随状态值的变化渲染更新

index.jsx

// 导入实例 User
import User from "./store/User.js";
// 导入 observer 函数
import { observer } from "mobx-react-lite";

// 用 observer 函数包裹目标组件
const Demo = observer(() => {
  return (
    <>
      {/* 获取实例 User 的属性 if_Login 的值 */}
      <div>登录状态:{User.if_Login ? "已登录" : "未登录"}</div>
      {/* 获取实例 User 的属性 info 值的 name 属性的值 */}
      <div>用户名称:{User.info.name}</div>

      {/* 调用实例 User 的方法 login,因有自定义传参,需使用箭头函数 */}
      <button onClick={() => User.login({ name: "朝阳" })}>登录</button>
      {/* 调用实例 User 的方法 logout */}
      <button onClick={User.logout}>登出</button>
    </>
  );
});

export default Demo;


最终效果

moxb 的自动计算 computed

与 vue 的 computed 概念相同,在响应式方法前加上 get 即可实现

src/store/Counter.js

import { makeAutoObservable } from "mobx";

class Counter {
  constructor() {
    makeAutoObservable(this, {}, { autoBind: true });
  }

  value = 0;

  increase() {
    this.value++;
  }
  // 用 get 装饰的方法,即computed,会随方法内响应式属性的变化,自动计算
  get double() {
    return this.value * 2;
  }
}

export default new Counter();

src/index.js

import Counter from "./store/Counter.js";

import { observer } from "mobx-react-lite";

const Demo = observer(() => {
  return (
    <>
      <div>计数器的值为:{Counter.value}</div>
      <div>双倍的计数器值为:{Counter.double}</div>
      <button onClick={Counter.increase}>+1</button>
    </>
  );
});

export default Demo;

moxb 监听属性

autorun

与 vue3 的 watchEffect 的概念相同,能监听所有属性的变化,且在页面初始化时就会执行一次

// autorun 需要导入
import { makeAutoObservable, autorun } from "mobx";

class Counter {
  constructor() {
    makeAutoObservable(this, {}, { autoBind: true });
  }

  value = 0;

  increase() {
    this.value++;
  }
}

// 因 autorun 函数内需要使用到实例的属性,需先将实例存入变量 counter
const counter = new Counter();

autorun(() => {
  //任一响应式属性变化时,都会执行,在页面初始化时,也会执行
  console.log("counter.value的值为", counter.value);
});
export default counter;

reaction

与 vue 的 watch 概念相同,可精准指定要监听的属性,在属性变化时才执行处理函数(可以获取到新值和旧值),再页面初始化时,不会执行。

// reaction 需要导入
import { makeAutoObservable, reaction } from "mobx";

class Counter {
  constructor() {
    makeAutoObservable(this, {}, { autoBind: true });
  }

  value = 0;

  increase() {
    this.value++;
  }
}

// 因 reaction 函数内需要使用到实例的属性,需先将实例存入变量 counter
const counter = new Counter();

reaction(
  // 第1个参数为要监听的属性
  () => counter.value,
  // 第2个参数为响应函数
  (newValue, oldValue) => {
    //仅在 value 属性变化时执行,在页面初始化时,不会执行
    console.log("counter.value的旧值为", oldValue);
    console.log("counter.value的新值为", newValue);
  }
);
export default counter;

moxb 处理异步

异步执行的代码,需放入 runInAction 函数中(否则会有需在 action 中修改状态的提示)

// runInAction 需要导入
import { makeAutoObservable, runInAction } from "mobx";

class Counter {
  constructor() {
    makeAutoObservable(this, {}, { autoBind: true });
  }

  value = 0;

  increase() {
    setTimeout(() => {
      // 异步执行的代码
      runInAction(() => {
        this.value++;
      });
    }, 1000);
  }
}

export default new Counter();

moxb 模块化

当 store 设计的类比较多时,为了方便使用,可以将其模块化为一个 store 中,方便页面的导入和使用。

1. 将分散的store,全部放入RootStore

新建文件 src/store/index.js

import { createContext, useContext  } from "react";

// 导入要统一管理的Store
import user from "./User.js";
import counter from "./Counter.js";

// 将分散的store,全部放入RootStore
class RootStore {
  user = user;
  counter = counter;
}

const store = new RootStore();
// 创建上下文
const Context = createContext(store);
// 导出自定义hook函数 --- useStore
export default function useStore() {
  // 返回 useContext
  return useContext(Context);
}

2. 页面中导入后,解构赋值使用

import { observer } from "mobx-react-lite";
// 导入自定义 hook 函数useStore
import useStore from "./store/index.js";

const Demo = observer(() => {
  // 解构赋值,获取到需要的 store
  const { counter, user } = useStore();
  return (
    <>
      <div>用户的登录状态为:{user.if_Login ? "已登录" : "未登录"}</div>
      <div>计数器的值为:{counter.value}</div>

      <button onClick={counter.increase}>+1</button>
    </>
  );
});

export default Demo;

目录
相关文章
|
3天前
|
前端开发 JavaScript 开发者
react18【系列实用教程】组件 (2024最新版 | 含父子组件传值、兄弟组件传值、越层组件传值、“插槽“)
react18【系列实用教程】组件 (2024最新版 | 含父子组件传值、兄弟组件传值、越层组件传值、“插槽“)
18 2
|
3天前
|
前端开发 JavaScript 数据格式
react18【系列实用教程】Hooks (useState,useReducer,useRef,useEffect,useContext,useMemo,useCallback,自定义 Hook )
react18【系列实用教程】Hooks (useState,useReducer,useRef,useEffect,useContext,useMemo,useCallback,自定义 Hook )
11 1
|
3天前
|
JavaScript 前端开发
react18【系列实用教程】双向绑定表单 (2024最新版)含受控组件、非受控组件、单行多行输入框 input,下拉选择 select,单选 radio,多选 checkbox,标签 label
react18【系列实用教程】双向绑定表单 (2024最新版)含受控组件、非受控组件、单行多行输入框 input,下拉选择 select,单选 radio,多选 checkbox,标签 label
9 1
|
3天前
|
JavaScript 前端开发
react18【系列实用教程】JSX (2024最新版)
react18【系列实用教程】JSX (2024最新版)
9 1
|
3天前
|
前端开发
react18【系列实用教程】Hooks 闭包陷阱 (2024最新版)含useState 闭包陷阱,useEffect 闭包陷阱,useCallback 闭包陷阱
react18【系列实用教程】Hooks 闭包陷阱 (2024最新版)含useState 闭包陷阱,useEffect 闭包陷阱,useCallback 闭包陷阱
6 0
|
3天前
|
JavaScript
react18【系列实用教程】useRef —— 创建 ref 对象,获取 DOM (2024最新版)
react18【系列实用教程】useRef —— 创建 ref 对象,获取 DOM (2024最新版)
6 0
|
3天前
|
缓存 前端开发
react18【系列实用教程】memo —— 缓存组件 (2024最新版)
react18【系列实用教程】memo —— 缓存组件 (2024最新版)
10 0
|
3天前
|
缓存
react18【系列实用教程】useCallback —— 缓存函数 (2024最新版)
react18【系列实用教程】useCallback —— 缓存函数 (2024最新版)
6 0
|
3天前
|
缓存
react18【系列实用教程】useMemo —— 缓存数据 (2024最新版)
react18【系列实用教程】useMemo —— 缓存数据 (2024最新版)
5 0
|
3天前
react18【系列实用教程】useReducer —— 升级版的 useState (2024最新版)
react18【系列实用教程】useReducer —— 升级版的 useState (2024最新版)
7 0