借助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同样,脏活累活都包装了起来,外部只须要优雅的调用,不用过多关心细节,你卯足了劲撸代码就完事儿?函数