设计思路
为共享数据生成setData()
与useData()
对。
-
setData()
: 初始化或更新共享数据 -
useData()
:为react hook,用于获取最新的共享数据
代码
import { useCallback, useEffect, useState } from 'react'
export default function factory(
service, initialValue
) {
let store, fetchPromise, reactions = []
const useData = () => {
const [current, setCurrent] = useState(store ?? initialValue)
const reaction = useCallback(() => setCurrent(store ?? initialValue), [])
useEffect(() => {
const run = async () => {
const currentFetchPromise = (fetchPromise = fetchPromise ?? service())
setCurrent(store = await currentFetchPromise)
fetchPromise = null
}
reactions.push(reaction)
if (!cache) run()
// hook destroy时,移除reaction
return () => reactions = reactions.filter(f => reaction !== f)
}, [])
return current
}
const setData = (data) => {
store = data
reactions.forEach(fn => fn()) // Call reactions
}
return { useData, setData }
}
使用例子:
// 创建数据共享钩子
export const {useData as useUserData, setData as setUserData } = factory(() => {
return Promise.resolve({ id: 123456, username: '请叫我Pro大叔' })
})
// Login Component
const Login = () => {
// 取值
const login = () => {
// after login
setUserData(userData);
}
....
}
// User Component
const User1 = () => {
// 取值
const user = useUserData()
....
}