|
| 1 | +import { useCallback, useEffect, useRef, useState } from "react" |
| 2 | +import { FIATCurrencies } from "./shared.d" |
| 3 | + |
| 4 | +const API_URL = "https://api.coingecko.com/api/v3/simple/price" |
| 5 | +const INITIAL_STATE = { usd: 0, jpy: 0, eur: 0 } |
| 6 | +const ONE_SEC_IN_MS = 1000 |
| 7 | +type CallBack = () => void |
| 8 | + |
| 9 | +const useTokenPrice = ( |
| 10 | + coinGeckoID: string, |
| 11 | + intervalInSecs: number = 60 |
| 12 | +): [FIATCurrencies, CallBack] => { |
| 13 | + const timer = useRef(null) |
| 14 | + const [price, setPrice] = useState(INITIAL_STATE) |
| 15 | + const [count, setCount] = useState(0) |
| 16 | + const triggerRefetch = useCallback(function memoizedRefetch() { |
| 17 | + setCount((n) => n + 1) |
| 18 | + }, []) |
| 19 | + useEffect(() => { |
| 20 | + clearTimeout(timer.current) |
| 21 | + fetch(`${API_URL}?ids=${coinGeckoID}&vs_currencies=usd,eur,jpy`) |
| 22 | + .then((r) => r.json()) |
| 23 | + .then((json) => { |
| 24 | + if (coinGeckoID in json) { |
| 25 | + setPrice((state) => ({ ...state, ...json[coinGeckoID] })) |
| 26 | + } |
| 27 | + }) |
| 28 | + .catch(console.error) |
| 29 | + .finally(() => { |
| 30 | + // Constrain interval not to be less than 10s |
| 31 | + const secs = intervalInSecs < 10 ? 10 : intervalInSecs |
| 32 | + setTimeout(triggerRefetch, secs * ONE_SEC_IN_MS) |
| 33 | + }) |
| 34 | + return () => clearTimeout(timer.current) |
| 35 | + }, [count]) |
| 36 | + |
| 37 | + return [price, triggerRefetch] |
| 38 | +} |
| 39 | + |
| 40 | +export default useTokenPrice |
0 commit comments