umi 3.x 实战,useModel 全局数据管理

7,023 阅读1分钟

其实很多项目,都可以用更轻便的 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 的模式