其实很多项目,都可以用更轻便的 useModel 来代替 redux 管理全局数据
例如,想要实现全局的窗口高度监听
// src/models/useBodyHeight.ts
// 如果想要 model 生效,就要在 models 文件夹中使用
import { useEffect, useState } from 'react'
export default () => {
const [bodyHeight, setBodyHeight] = useState(document.body.clientHeight)
// 监听窗口尺寸变化
useEffect(() => {
const changeHeight = () => setBodyHeight(document.body.clientHeight)
window.addEventListener('resize', changeHeight)
return () => window.removeEventListener('resize', changeHeight)
}, [])
return bodyHeight
}
// xxx.tsx
import { useModel } from 'umi'
export default function Common() {
// 每次窗口大小变化的时候,都能在任何组件使用最新的窗口高度
const bodyHeight = useModel('useBodyHeight')
}
全局 loading
// src/models/useLoading.ts
export default () => useState(false)
// 当深层次的子组建需要触发全局的 loading 效果
export default function Common() {
// 这里的第二个函数参数接受 useLoading 的返回值并返回一个值,useModel 将这个返回值传给组件,并将该值作为组件更新的依赖,即使 loading 改变了,也不会触发该组件的更新
const setLoading = useModel('useLoading',(model) => model[1])
...
}
同理,也可以在 useModel 中使用 useReducer,做成类似于 redux 的模式