umi3升级Umi Max 的useModel问题

1,559 阅读3分钟

能跑就不要瞎升级,一直不升级,一直爽

最近有个老项目,发现是umi3开发的,去翻了下umi的官网,发现现在官网已经升级到umi4了,甚至还有更进一步的umi max。

因为刚好也不熟悉umi3,umi3和umi4对我来说,都是熟悉的陌生人,后来一想,干脆升级算了,翻了下官网umi3升级umi4也不是很复杂。

没想到这是痛苦的开始,太难了😄

umi3升级umi max的一堆配置错误修改就不赘述了,一把鼻涕一把泪。

好不容易错误修改完,跑起来以后,发现useModel 的使用一直有问题。

吐槽一下,umi的官网只是烂,明明说useModel是自定义hooks,但是官网给出的例子,我不明白为什么不使用use开头。

image.png

而且明明是umi max的文档,为什么例子引入useModel还是通过umi引入呢???

image.png

真是一头雾水。。。

吐槽结束了,还是书回正题吧

文档说umi max 所做的工作就是将其中的状态或数据变成了全局数据,不同的组件在使用该 Model 时,拿到的是同一份状态或数据。

这里是没有任何问题

目前我项目里边代码是这样使用的,在目录src/models目录下建立一个useUsersModel.ts文件

import React, { useEffect } from 'react';
import { getUsers } from '@/services';
import transform from '../utils/transform';
/**
 * 聊天用户map
 */
export default function useUsersModel() {
  const [users, setUsers] = React.useState<Map<number, API.User>>(() => {
    return new Map<number, API.User>();
  });

  useEffect(() => {
    getUsers().then((res) => {
      // setCurrent(undefined);
      setUsers(() => {
        const map = new Map<number, API.User>();
        res.data.forEach((v) => {
          map.set(v.id, v);
        });
        // connect();
        return map;
      });
    });
  }, []);

  return {
    users,
    setUsers,
  };
  // return transform({
  //   users,
  //   setUsers,
  // });
}

代码很简单,就是简单的一个自定义hooks,在组件里边直接使用useModel就可以直接拿到当前的状态。

image.png

这里代码非常简单,就是类似useState的使用方法,但是问题就是出现在setUsers上面,因为我们useModel把我们定义的model文件,给升级成全局的状态。

问题就出现在这里,原来在umi3中是可以使用setUsers进行改变users的状态, 但是我发现当我升级成umi max后,当我使用setUsers 改变users的状态的时候,但是在其它组件里边,使用useModel拿到的状态,仍然是旧的users。

换个说法就是,当我在A组件里边使用setUsers改变users的状态的时候,但是在B组件里边拿到的仍然是users的旧状态。

代码如下:

A组件:

import { useModel } from '@umijs/max';

function A() {
const { users, setUsers } = useModel('useUsersModel');

useEffect(() => {
    setUsers(...)
}, [])

B组件:

import { useModel } from '@umijs/max';

function B() {
const { users, setUsers } = useModel('useUsersModel');

useEffect(() => {
//   这里仍然是旧的users,当在A组件修改后,B组件仍然拿不到新的users
console.log(users)
}, [users])

不知道什么原因,我以为umi max 里边useModel把我们在src/models下定义的状态,提取成全局状态后,方法应该也相应的提取成全局方法,行为和umi3是一样的。

但是很显然应该没有。

这里也是我不是很理解的地方,不知道是不是我升级的配置,哪里没有配置对,反正就是状态无法全局更新,不知道是基于什么考虑,为什么不和umi3一样。

官网去翻了下,好像也没相关说明,网上也没找到解决方法,实在不行只能去翻源码。

去翻了下useModel的源码,它这里主要是使用context, 把我们定义的model变成全局的状态,如果想要修改model的状态,需要在model文件里边,二次封装一下。

所以这里需要去把model的文件内容重新定义下,修改src/models/useUsersModel.ts文件

image.png

这样修改后,在A组件里边使用setUsers修改状态的时候,B组件就可以拿到最新的状态啦。