使用原因
由于管理端是采用umi
和antd
来开发,而其中的全局状态是采用umi
的useModel
来进行管理的。使用感受就是用起来挺舒服的。
在小程序的开发中也需要用到全局的状态管理,一开始为了赶进度,没多想以为useModel
只能用在umi
,然后就采用单例模式来进行维护全局的状态了,但是采用这种方法最大的弊端就是每次数据更改,都要手动render
一下,然后页面与页面之间数据变化了,又要处理什么时候该render
。
现在有点时间研究,发现umi
的useModel
原来已经给我们打包好了,只需稍稍处理就能在其他项目中使用了。
开始抽离
在umi
项目中的路径为:src/.umi/plugin-model,把plugin-model
整个文件夹复制到其他项目中
打开useModel.tsx
,进入isEqual
里面然后把整个文件也粘出来。
打开Provider.tsx
,将里面的initialState
也粘出来。
// 里面就这样一行代码(想怎么处理都行)
export default () => ({ loading: false, refresh: () => {} })
在其他项目中使用
- 因为
useModel
主要是采用了useContext
来进一步封装出来的钩子,所以想要全局使用,就要在整个项目最外层包裹一层。我这里是taro小程序中使用,所以就包裹在这里了,当然也可以只包裹需要使用的那些父组件(这样就是那些父组件和里面的子组件才能使用了)。
- 在
model
文件夹中(在其他文件中也行),简单写一个model
import { useState, useCallback } from 'react';
type UserInfo = {
avatar?: string;
name?: string;
};
export default function useAuthModel() {
const [userInfo, setUserInfo] = useState<UserInfo>({name: 'lhh'});
const setUser = useCallback((userInfo: UserInfo) => {
setUserInfo(userInfo);
}, []);
return {
userInfo,
setUser,
};
}
- 引入自己的
model
,打开Provider.tsx
,手动引入
- 简单使用
import NavBar from '@/components/navBar';
import { View, Button } from '@tarojs/components'
import Taro from '@tarojs/taro';
import './index.less';
import { useModel } from "@/hooks/useModel";
export default () => {
// 这里的 user-info 就是第三步引入的时候自己写的 key 值
const { userInfo } = useModel('user-info')
return (
<View className='page-test-useModel'>
<NavBar title={'test-页面一'} />
<View className="name">这里是父组件:{userInfo?.name}</View>
<Children></Children>
<Button onClick={() => Taro.navigateTo({url: '/pages/aatest-useModel2/index'})}>去下个页面</Button>
</View>
)
}
const Children = () => {
const {userInfo, setUser} = useModel('user-info')
return (
<View className='com-useModel-c-t'>
<View className="title">--子组件--</View>
子组件姓名:{userInfo?.name}
<Button className="btn" onClick={() => {
setUser({...userInfo, name: 'lhh改名了' + Date.now()})
}}>子组件改名</Button>
</View>
)
}