Mobx 是一个和 React 良好配合的集中状态管理工具,mobx 和 react 的关系,相当于 vuex 和 vue
同类工具还有 redux、dva、recoil 等

环境配置

Mobx 是一个独立响应式的库,可以独立于任何 UI 框架存在,但是人们通常把它和 React 绑定起来使用,用 Mobx 来做响应式数据建模,React 作为 UI 视图框架来渲染内容

环境配置需要三个部分

  • 一个通过 create-react-app 创建好的项目环境
  • mobx 本身
  • 一个链接 mobx 和 react 的中间部件
  1. 使用 create-react-app 初始化项目
npx create-react-app mobx-react-app
  1. 安装 mobx 和 mobx-react-lite
yarn add mobx mobx-react-lite
npm i mobx mobx-react-lite

第一个 store

初始化 mobx

实现步骤

  1. 定义数据状态(state)
  2. 数据相应式处理
  3. 定义 action 函数(修改数据)
  4. 实例化并导出实例
import { makeAutoObservable } from "mobx";

// 编写一个mobx store小案例
class CounterStore {
  // 1. 定义数据
  count = 0;
  constructor() {
    // 2.把数据弄成响应式
    makeAutoObservable(this);
  }
  // 3.定义action函数(修改数据)
  addCount = () => {
    this.count++;
  };
}
// 4.实例化 然后导出给react使用
const counterStore = new CounterStore();
export { counterStore };
连接 react

实现步骤

  1. 导入 store 实例
  2. 使用 store 中的数据
  3. 修改 store 中的数据
  4. 让组件视图响应数据变化
import React from "react";
// 导入
import { counterStore } from "./store/counter";
// 导入中间件连接mobx-react完成响应式变化
import { observer } from "mobx-react-lite";
function App() {
  return (
    <div>
      {/* 渲染store中的counter */}
      <h1>{counterStore.count}</h1>
      {/* 点击事件触发action函数修改count值 */}
      <button onClick={counterStore.addCount}>累加</button>
    </div>
  );
}
// 包裹App
export default observer(App);

mobx-computed 计算属性

基于一个原始的数据,经过一定的计算得到一个新数据,且能在原始数据发生变化的时候完成重新计算.

computed-如何实现
  1. 声明一个存在的数据
  2. 定义 get 计算属性
  3. 在 makeAutoObservable 方法中标记
import { makeAutoObservable } from "mobx";
class CounterStore {
  //   定义一个原始数据list
  list = [1, 2, 3, 4, 5, 6];
  constructor() {
    makeAutoObservable(this);
  }
  //   定义计算属性
  get filterList() {
    return this.list.filter((item) => {
      return item > 2;
    });
  }
  //修改list
  addList = () => {
    this.list.push(7, 8, 9);
  };
}
const counterStore = new CounterStore();
export { counterStore };

在 react 中使用

import React from "react";
import { counterStore } from "./store/counter";
import { observer } from "mobx-react-lite";
function App() {
  return (
    <div>
      {/* 使用计算属性 */}
      {counterStore.filterList}
      <button onClick={counterStore.addList}>修改list</button>
    </div>
  );
}
// 包裹App
export default observer(App);

Mobx 模块化

一个项目中有很多业务模块,我们不能把所有代码都写到一起,这样很难维护,为了提供可维护性,需要引入模块化
比如上面的例子,我们要拆分 count 和 list 模块

  1. 拆分 count 和 list 模块,每个模块定义自己独立的 state/actions
  2. 在 store/index.js 下导入拆分后的模块,进行模块组合
  3. 使用 React 的 useContext 机制导出 useStore 方法,供业务组件统一使用.

liststore.store.js

import { makeAutoObservable } from "mobx";
class ListStore {
  list = ["Vue", "React"];
  constructor() {
    makeAutoObservable(this);
  }
  addList = () => {
    this.list.push("Angular");
  };
}
export { ListStore };

counter.store.js

import { makeAutoObservable } from "mobx";

// 编写一个mobx store小案例
class CounterStore {
  // 1. 定义数据
  count = 0;
  //   定义一个原始数据list
  list = [1, 2, 3, 4, 5, 6];
  constructor() {
    // 2.把数据弄成响应式
    makeAutoObservable(this);
  }
  //   定义计算属性
  get filterList() {
    return this.list.filter((item) => {
      return item > 2;
    });
  }
  //修改list
  addList = () => {
    this.list.push(7, 8, 9);
  };
  // 3.定义action函数(修改数据)
  addCount = () => {
    this.count++;
  };
}
export { CounterStore };

index.js

// 组合子模块
// 封装统一导出的供业务使用的方法
import React from "react";
import { ListStore } from "./list.store";
import { CounterStore } from "./counter.store";
// 1. 声明一个rootStore
class RootStore {
  constructor() {
    // 对子模块进行实例化操作
    // 将来实例化根store的时候
    // 根store有两个属性 分别是counterStore和listStore
    // 各自对应的值,就是我们导入的子模块实例对象
    this.counterStore = new CounterStore();
    this.listStore = new ListStore();
  }
}
// 实例化操作
const rootStore = new RootStore();
// 使用react conntext机制 完成统一方法封装
// Provider value={传递的数据}
// 查找的机制: useContext 优先从Provider value找 如果找不到 就会找createContext方法传递过来的默认参数
const context = React.createContext(rootStore);
// 这个方法作用:通过useContext拿到rootStore实例对象 然后返回
// 只要在业务组件中 调用useStore()->rootStore
const useStore = () => React.useContext(context);
export { useStore };

App.jsx

import React from "react";
import { useStore } from "./store/index";
import { observer } from "mobx-react-lite";
function App() {
  const rootStore = useStore();
  console.log(rootStore);
  return (
    <div>
      {rootStore.counterStore.count}
      <button onClick={rootStore.counterStore.addCount}>累加</button>
    </div>
  );
}

export default observer(App);

也可以用解构赋值
App.jsx

import React from "react";
import { useStore } from "./store/index";
import { observer } from "mobx-react-lite";
function App() {
  const { counterStore } = useStore();
  console.log(counterStore);
  return (
    <div>
      {counterStore.count}
      <button onClick={counterStore.addCount}>累加</button>
    </div>
  );
}
export default observer(App);

Q.E.D.


永远自由,永远热爱