Umi项目使用useModel实现全局数据共享

2023-08-25 13:44:15 浏览数 (1)

之前有一个 Umi 项目写的比较乱,定义了一个变量,用来统一存放所有的系统参数,父子组件通过 Context 和 props 传值。

现在发现一个问题,因为这个变量中有一部分参数是常量,有一部分又是需要动态修改的,所以每次修改这个变量,都会重新渲染页面,页面多次渲染后最后赋值的值会丢失。

所以准备改造一下,将常量和后期会变化的参数拆分开,使用 dva 来实现全局共享数据,了解到 Umi 官方有一个 @umijs/plugin-model 插件可以满足需求。

@umijs/plugin-model

一种基于 hooks 范式的简易数据管理方案(部分场景可以取代 dva),通常用于中台项目的全局共享数据。

我们都知道自定义 hooks 是逻辑复用的利器,但我们也知道它不能复用状态,就和 react 内置的 hooks 一样,每次调用产生的状态都是相互隔离、无关的。那么,在业务开发中,如果我们需要提取的逻辑和状态都希望能够在多个组件中『共享』,就像其他数据流管理工具(dvamobx)一样,@umijs/plugin-model 就是一个不错的选择。

启用方式

src/models 目录下有 hooks model 时启用。

介绍

我们约定在 src/models 目录下的文件为项目定义的 model 文件。每个文件需要默认导出一个 function,该 function 定义了一个 Hook,不符合规范的文件我们会过滤掉。

文件名则对应最终 model 的 name,你可以通过插件提供的 API 来消费 model 中的数据。

所谓 hooks model 文件,就是自定义 hooks 模块,没有任何需要使用者关注的黑魔法。请看示例:

/src/models/common.ts

代码语言:javascript复制
import { GLOBAL_DATA } from '@/constant/global';
import { useState } from 'react';

const commonData = () => {
  const [globalData] = useState<Record<string, any>>(GLOBAL_DATA);
  const [selectZzjg, setSelectZzjg] = useState<Record<string, any>>(
    GLOBAL_DATA?.defaultZZJG,
  ); // 组织机构
  return {
    globalData,
    selectZzjg,
    setSelectZzjg,
  };
};

export default commonData;

这就是一个普通的自定义 hooks,但 @umijs/plugin-model 把其中的状态变成了『全局状态』,多个组件中使用该 model 时,拿到的同一份状态。

useModel

useModel 是一个 Hook,提供消费 Model 的能力,使用示例如下:

代码语言:javascript复制
import { useModel } from 'umi';
export default () => {
  const { user, fetchUser } = useModel('user', model => ({ user: model.user, fetchUser: model.fetchUser }));
  return <>hello</>
};

useModel 有两个参数,namespace 和 updater

  • namespace - 就是 hooks model 文件的文件名,如上面例子里的 useAuthModel
  • updater - 可选参数。在 hooks model 返回多个状态,但使用组件仅引用了其中部分状态,并且希望仅在这几个状态更新时 rerender 时使用(性能相关)。

可以在任意页面使用和修改它的值:

代码语言:javascript复制
const { globalData, selectZzjg, setSelectZzjg } = useModel('common');
setSelectZzjg('股份公司')

未经允许不得转载:w3h5-Web前端开发资源网 » Umi项目使用useModel实现全局数据共享

0 人点赞