Mobx6 在react中的正确使用

139 阅读3分钟

mobx介绍

MobX 是一个身经百战的库,它通过运用透明的函数式响应编程(Transparent Functional Reactive Programming,TFRP)使状态管理变得简单和可扩展。可以理解为响应式状态管理

项目背景

npmversion
react18.2+
mobx6+
mobx-react-lite4+

如何使用

1. mobx 下载


npm i mobx -s
npm i mobx-react-lite -s // 组件函数方式
npm i mobx-persist-store -s // 缓存本地- 根据项目需求下载

2. 创建store/modules/login.store.ts

image.png

import { makeAutoObservable } from "mobx";
import { authApi } from "@/api/index";
import { makePersistable } from "mobx-persist-store";

type Token = string | undefined | null;

class AuthStore {
  token: Token = undefined;
  constructor() {
    makeAutoObservable(this);
    makePersistable(this, {
      name: "AuthStore", // 存储到localStorage当中的key值是什么,此处为字符串string;
      properties: ["token"], // 需要持久化的数据是什么,此数据需要为上面声明了的变量,并且传值方式为[string]
      storage: window.localStorage, // 你的数据需要用那种方式存储,常见的就是localStorage
    });
  }

  get getToken(): Token {
    return this.token;
  }

  setToken(val: string): void {
    this.token = val;
  }

  /* 登录 */
  async login(data: object) {
    const result = await authApi.login(data);
    if (!result) return false;

    return result.data;
  }
}

const useAuthStore = new AuthStore();

export default useAuthStore;

3. 创建store/index.ts

import React from "react";
import useLoginStore from "./modules/login.store";

class RootStore {
  useLoginStore = useLoginStore;
}

const rootStore = new RootStore();
// 这里可以使用React context 完成统一方法的封装需求
const context = React.createContext(rootStore);
// 封装useStore方法,业务组件调用useStore方法便就可以直接获取rootStore
const useStore = () => React.useContext(context);

export default useStore;


4. login.tsx 使用

import { observer } from "mobx-react-lite";
import useStore from "@/store";
const Login = observer(() => {
  const { useAuthStore } = useStore();
  return <div>{useAuthStore.getToken}</div>;
});
const ObservedLogin = Login;
export default ObservedLogin;

mobx6 常用方法解释

1. makeAutoObservable(this) 自动响应式绑定属性,可读属性,设置方法。

**使用场景**- store引用,请看上方步骤2

**推断规则**-   所有 *自有* 属性都成为 `observable`-   所有 `get`ters 都成为 `computed`-   所有 `set`ters 都成为 `action`-   所有 *prototype 中的 functions* 都成为 `autoAction`-   所有 *prototype 中的 generator functions* 都成为 `flow`。(需要注意,generators 函数在某些编译器配置中无法被检测到,如果 flow 没有正常运行,请务必明确地指定 `flow` 注解。)
-   在 `overrides` 参数中标记为 `false` 的成员将不会被添加注解。例如,将其用于像标识符这样的只读字段。

2. observer(组件) 一个高阶组件,可用来在 observable 发生改变时将一个 React 函数组件或类组件重新渲染。

**使用场景**- 组件引用,请看上方步骤4

**注意**- observer 包含了react `memo` ,无需再次添加
- 组件传参不变,举例:observer(({name,age})=>{...})

3. toJS(value) 将响应式对象转换为普通对象

**使用场景**:
- 组件、store 都可以,
  
```jsx
import { toJS } from 'mobx';
const { useAuthStore } = useStore();
const val = toJS(useAuthStore.getKoken)
```

更多方法:api参考手册

其他场景使用——注意事项

1. 当前login.store.ts文件引入其他sotre方法或属性

import HomeStore from './home.store'

class AuthStore {
    ...
    setName(val){
        this.name = HomeStore.getKey + val
    }
}

2. 非组件引用store,比如axios.http.ts

不能引入 @/store/index,因为在 【如何使用-步骤3】React.useContext定义了上下文,只能在组件中使用

import LoginStore from '@/store/login.store'

Service.interceptors.request.use((config) => {
  const token = LoginStore.getToken;
  if (token) config.headers.token = token;
  return config;
});

3.observer 实现效果

效果1
import { observer } from 'mobx-react-lite';
const LoginTmp = observer(()=>{
    return <div>...</div>
})

export default LoginTmp
效果2
import { observer } from 'mobx-react-lite';
const LoginTmp = ()=>{
    return <div>...</div>
}

export default observer(LoginTmp)