React18状态管理方案之MobX

408 阅读5分钟

指示图

MobX.png

参考文档

MobX中文文档MobX学习相关文档MobX英文文档

什么是MobX?

MobX是一个用于管理应用状态的库,它的核心理念是“透明响应式编程”。MobX提供了一种简便的方式来管理状态,使您能够轻松地在组件之间共享状态并保持UI与状态同步。

安装MobX

要在React项目中使用MobX,首先需要安装MobX和MobX的React绑定库(mobx-react)。可以通过npm或yarn进行安装:

pnpm add mobx mobx-react

对类属性使用符合规范的转换

这段为官方原话: 当 MobX 与 TypeScript 或者 Babel 一起使用时,并且你计划使用类,一定要更新你的配置,才能为类字段启用一个符合 TC-39 规范的转译,因为这不总是默认值。否则,无法在初始化类字段之前使其可观察。

  • Babel:一定要用至少 7.12 版,并有以下配置:

    {
        // Babel < 7.13.0
        "plugins": [
            ["@babel/plugin-proposal-class-properties", { "loose": false }]
        ],
    
        // Babel >= 7.13.0 (https://babeljs.io/docs/en/assumptions)
        "plugins": [["@babel/plugin-proposal-class-properties"]],
        "assumptions": {
            "setPublicClassFields": false
        }
    }
    
  • TypeScript:设置编译器选项为 "useDefineForClassFields": true

将以下代码插入你源码的开头(如 index.js)以便校验:

if (!new (class { x; })().hasOwnProperty("x"))
    throw new Error("转译器配置错误");

基本概念

  1. Observable:可观察对象,状态对象的属性会被MobX自动转换为可观察的。
  2. Action:用于修改状态的函数。
  3. Computed:计算值,基于其他状态生成的值, MobX 会根据依赖进行优化。
  4. Observer:用于将组件标记为观察者,使组件能够在状态变化时自动重新渲染。

原则

image.png

在MobX中,使用 action 来更新状态是一个重要的概念。这是一种推荐的做法,因为它使得代码更加明确和可维护。action 确保了所有对状态的修改都集中在特定的方法中,从而增强了代码的可读性和调试的便利性。

以下是在React中使用MobX进行状态管理并通过action更新状态的详细步骤:

1. 安装MobX

首先确保你已经在项目中安装了mobxmobx-react。如果还没有安装,可以通过下面的命令进行安装:

pnpm add mobx mobx-react

2. 创建MobX Store

"mobx": "^6.13.5" "mobx-react": "^9.1.1"

在你的项目中创建一个状态存储(Store),并使用action来更新状态。

// store.ts
import { makeAutoObservable, action } from "mobx";

class Store {
    count = 0;

    constructor() {
        makeAutoObservable(this); // 使状态可观察
    }

    // 使用 action 来更新状态
    increment = action(() => {
        this.count++;
    });

    decrement = action(() => {
        this.count--;
    });

    reset = action(() => {
        this.count = 0;
    });
}

const store = new Store();
export default store;

3. 在React组件中使用Store

在组件中导入并使用MobX Store。当需要更新状态时调用对应的action

// App.js
import React from "react";
import { observer } from "mobx-react";
import store from "./store";

const App = observer(() => {
    return (
        <div>
            <h1>计数器: {store.count}</h1>
            <button onClick={() => store.increment()}>增加</button>
            <button onClick={() => store.decrement()}>减少</button>
            <button onClick={() => store.reset()}>重置</button>
        </div>
    );
});

export default App;

4. 根文件(index.ts)

确保在根文件中渲染这个组件。

// index.ts
import { StrictMode } from 'react'
import App from './App.tsx'
import './index.css'

createRoot(document.getElementById('root')!).render(
  <StrictMode>
     <App />
  </StrictMode>,
)

5. 运行应用

现在,启动你的React应用,你会看到一个简单的计数器,能够通过点击按钮来增加、减少和重置计数。

总结

在MobX中,使用action更新状态是一个最佳实践,它确保了对状态的所有变更都是可控和组织良好的。通过这种方式,开发者能够更清楚地了解何时及如何修改状态,从而提高应用的可维护性和可扩展性。

注意事项

  • 你可以使用runInAction来将多个状态更新组合在一个action中。例如:

    import { runInAction } from "mobx";
    
    // 在其他地方,例如在异步函数中
    async someAsyncFunction() {
        const newCount = await fetchData();
        runInAction(() => {
            this.count = newCount; // 将状态更新放在 runInAction 中
        });
    }
    

这种方式确保了在状态更新时的行为和反应的透明性。

6. computed

MobX提供computed属性来计算派生状态。你可以将一些状态通过计算值封装到store中。

// store.js(补充部分)
import { computed } from "mobx";

class CounterStore {
    // ...其他代码...

    // get装饰即可实现 computed计算属性 
    get doubleCount() {
        return this.count * 2;
    }
}

// Counter.ts(补充部分) observer 函数包裹组件,这样才可以状态改变页面重新渲染

const Counter = observer(() => {
    return (
        <div>
            <h1>计数器: {counterStore.count}</h1>
            <h2>双倍计数器: {counterStore.doubleCount}</h2>
            <button onClick={() => counterStore.increment()}>增加</button>
            <button onClick={() => counterStore.decrement()}>减少</button>
            <button onClick={() => counterStore.reset()}>重置</button>
        </div>
    );
});

7. 将Store与组件分离

尽量将状态管理逻辑(Store)与UI逻辑分开。这可以使代码更加模块化,并有助于进行单元测试。

8. 适当使用局部状态

尽管MobX适合管理全局应用状态,但在某些情况下,利于简单组件使用局部状态,例如useState。在需要频繁更改并只在当前组件中使用的情况下,局部状态可以更简化。

9. 维护Store的可测试性

为了提高Store的可测试性,尽量将复杂的逻辑分离到个别方法中,并使用依赖注入来减少对外部依赖的直接引用。

10. 监控性能

当你的应用变得复杂时,注意性能问题。使用MobX的调试工具(如MobX DevTools)来监控状态变化和组件渲染。

11. 使用TypeScript

如果可能的话,考虑在开发中使用TypeScript。使用TypeScript可以为你的MobX Store提供类型安全,减少运行时错误。

总结

使用MobX进行状态管理时,遵循上述最佳实践可以增强代码的可维护性、可扩展性和可读性。通过合理组织和封装状态管理逻辑,可以创建出健壮的React应用,提升开发效率和用户体验。