React+TypeScript+Mobx6

  • react hook 风格下不再使用class类的形式定义组件,也就不再适用mobx以前版本的装饰器语法。
  • 以下分享 reack hook 语法风格下使用 mobx v6 版本的状态管理配置使用方式。
  相关依赖:
    "mobx": "^6.8.0",
    "mobx-react-lite": "^3.4.2",
    "react": "^18.2.0",

一、Mobx

  • mobx 是 react 生态中常用的状态管理插件之一,特点是配置及使用方式比较简便,方式上和 vuex 有些相似

  • 官方中文文档:https://zh.mobx.js.org/react-integration.html

  • mobx-react-lite 是配合 react 使用的一个轻量化插件,只支持函数式组件,适合 react hook

  • 官方已不建议使用装饰器语法,主要原因是js装饰器在现在的 ES 规范中并不成熟(目前在stage-2提案阶段且迟迟无法推进),而且引入装饰器语法也会增加打包后的代码体积。这里也将完全放弃装饰器方式。

  • 以下配置使用 react context 方式来传递数据,这也是官方推荐的方式。因为直接引用store原始数据在有多个module模块下可能会使引用变得杂乱,管理维护困难且不利于单元测试。

二、环境配置

  • 先安装依赖:yarn add mobx mobx-react-lite

1、配置 store/model

  • 创建 根store src/store/index.js:
  import User from './modules/user'
  • 创建 User模块 src/store/modules/user.js
  import { makeAutoObservable } from "mobx";

  export default class User {
    name: string
    firstName: string
    lastName: string

    constructor() {
      this.name = "张三"
      this.firstName = '张'
      this.lastName = '三'
      makeAutoObservable(this);
    }
    get copName() {
      return this.firstName + this.lastName;
    }
    changeName() {
      this.name = "李四"
    }
  }                                                      
  • makeAutoObservable 会将你定义的数据自动转化为相应类型的可观察对象,例如 constructor 里定义的转化为 state,get 定义的函数转化为 computed,非 get 定义的函数转化为 action。

2、配置 context

  • 创建 store 状态管理的 context 文件 src/contexts/storeContext.js
  import React from 'react'
  import store from '@/store'

  const storeContext = React.createContext(store)

  export default storeContext
  • 使用 react context 向下级传递,来共享全局可观察数据。

3、配置 hook

  • 创建 store 状态管理的 hook 文件 src/hooks/storeHook.js
  import { useContext } from 'react'
  import StoreContext from '../context/storeContext'
  import { observer } from 'mobx-react-lite'

  function useStore () {
    const store = useContext(StoreContext)
    return store
  }

  export {
    observer,
    useStore,
  }
  • 导出的 useStore 用于获取store数据。后续页面或组件都通过引用这个hook来获取store数据。
  • 导出的 observer 用于监听store数据的改变,同步到组件数据中。后续页面或组件如需要响应store数据的变化,就引用它包裹一下页面或组件的默认导出函数即可。
  • 这里将 mobx-react-lite 的 observer 在hook里导出是为了使用方便,一个hook就能引入全部所需。

4、引入 store

  • 项目入口文件 src/index.js 里引用
  import React from 'react';
  import { useStore, observer } from './hook/sotreHook'; 
  import './App.css';

  function App() {
    const sotre:any = useStore()
    console.log('userStore: ', sotre.user);
    return (
      <div className="App">
        <p>{sotre.user.name}</p>
        <p>{sotre.user.copName}</p>
        <button onClick={
          ()=> {
            sotre.user.changeName()
          }
        }>变更姓名</button>
      </div>
    );
  }

  export default observer(App);

三、使用

1、获取/响应 store 数据

  • 示例组件 src/App.tsx
import React from 'react';
import { useStore, observer } from './hook/sotreHook'; 
import './App.css';

function App() {
  const sotre:any = useStore()
  console.log('userStore: ', sotre.user);
  return (
    <div className="App">
      <p>{sotre.user.name}</p>
      <p>{sotre.user.copName}</p>
      <button onClick={
        ()=> {
          sotre.user.changeName()
        }
      }>变更姓名</button>
    </div>
  );
}

export default observer(App);
  • 通过自定义的 storeHook 来使用 store 的数据。
  • 如果只是获取一次 store 的数据而无需响应 store 数据的变化,只需要引用 useStore 即可。
  • 如果需要响应 store 数据的变化,即时更新到视图,就需要引用 observer,然后包裹一下该页面或组件的默认导出函数,即可实现响应式。
posted @ 2023-03-08 11:36  HuangBingQuan  阅读(185)  评论(0编辑  收藏  举报