藉助lodash的isEqual實現react
import { isEqual } from 'lodash';function useDeepCompareEffect(fn, deps){const comparisons = useRef(0);const prevDeps = useRef(deps);if(!isEqual(prevDeps.current, deps)){ comparisons.current++; } prevDeps.current = deps;return useEffect(fn, [comparisons.current]); }複製代碼
藉助AbortController類控制fetch方法的signal字段,AbortController.signal標記一次請求,在合適的時候調用AbortController.abort()取消該次請求,查看瀏覽器兼容性api
export function useFetch = (config, deps) => { const abortController = new AbortController() const [loading, setLoading] = useState(false) const [result, setResult] = useState() useEffect(() => { setLoading(true) fetch({ ...config, signal: abortController.signal }) .then((res) => setResult(res)) .finally(() => setLoading(false)) }, deps) useEffect(() => {return () => abortController.abort() }, []) return { result, loading } }複製代碼
因爲react內部的狀態更新機制,在同一個代碼塊內,setState後是沒法當即獲取到新值的,class組件裏面能夠經過回調函數,或者利用setTimeout之類跳出當前try塊從而獲取新值,爲了更方便的獲取值,能夠利用useRef.current值可變可是在組件整個生命週期內保持不變的特性,實現一個橋樑瀏覽器
export const useRefState = <T>( initialValue: T ): [React.MutableRefObject<T>, React.Dispatch<React.SetStateAction<T>>, T] => { const [state, setState] = useState<T>(initialValue); const refState = useRef(state); useEffect(() => { refState.current = state; }, [state]); return [refState, setState, state]; }複製代碼
藉助useRef的特性,因此也能夠實現定時器的控制ide
export const useTimeout = useCallback((callback: any, timeout: number = 3000) => { let callbackRef = useRef<any>(); useEffect(() => { callbackRef.current = callback; }); useEffect(() => {let id = setTimeout(() => callbackRef.current && callbackRef.current(), timeout);return () => clearTimeout(id); }, [timeout]) }, [])複製代碼
當本身嘗試寫過幾個自定義的hook以後,想必都能感覺到hook給開發者帶來的便利,這種感受就像寫了一個邏輯層面的jsx同樣,髒活累活都包裝了起來,外部只須要優雅的調用,不用過多關心細節,你卯足了勁擼代碼就完事兒?函數