Last active
November 4, 2020 07:34
-
-
Save popo1221/e150df4164e600e23aabcc0dd7f95e2a to your computer and use it in GitHub Desktop.
一个简易的React数据共享方式
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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