前端面试复习系列之react-hooks

监听深度依赖的值变化

借助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]);
}复制代码

自动取消api请求

借助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 }
}复制代码

setState事后当即获取新值

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

相关文章
相关标签/搜索