Skip to content

Instantly share code, notes, and snippets.

@popo1221
Last active November 4, 2020 07:34
Show Gist options
  • Select an option

  • Save popo1221/e150df4164e600e23aabcc0dd7f95e2a to your computer and use it in GitHub Desktop.

Select an option

Save popo1221/e150df4164e600e23aabcc0dd7f95e2a to your computer and use it in GitHub Desktop.
一个简易的React数据共享方式
import { useCallback, useEffect, useState } from 'react'
type ServiceType<T> = () => Promise<T>
interface ReturnType<T> {
useData: () => T
clearData: () => void
setData: (data: T) => void
}
export default function createDataHook<T>(
service: ServiceType<T>,
initialValue: T
): ReturnType<T> {
let reactions = []
let cache: T
let fetchPromise: Promise<T>
const useData = () => {
const [current, setCurrent] = useState<T>(cache ?? initialValue)
const reaction = useCallback(() => {
setCurrent(cache ?? initialValue)
}, [])
useEffect(() => {
const run = async () => {
const currentFetchPromise = (fetchPromise = fetchPromise ?? service())
cache = await currentFetchPromise
setCurrent(cache)
fetchPromise = null
}
reactions.push(reaction)
if (!cache) {
run()
}
return () => {
reactions = reactions.filter(f => reaction !== f)
}
}, [])
return current
}
const clearData = () => {
cache = null
// Call reactions
reactions.forEach(fn => fn())
}
const setData = (data: T) => {
cache = data
// Call reactions
reactions.forEach(fn => fn())
}
return {
useData,
setData,
clearData
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment