React

useMemoizedFn 和 useEvent 的差异

https://mp.weixin.qq.com/s/-6bQKIjH6WPcfuiCFtsjng

  1. function useMemoizedFn(fn) {
  2. const fnRef = useRef(fn);
  3. fnRef.current = useMemo(() => fn, [fn]);
  4. return useCallback((...args) => {
  5. return fnRef.current.apply(args);
  6. }, []);
  7. }
  1. // (!) Approximate behavior
  2. function useEvent(handler) {
  3. const handlerRef = useRef(null);
  4. // In a real implementation, this would run before layout effects
  5. useLayoutEffect(() => {
  6. handlerRef.current = handler;
  7. });
  8. return useCallback((...args) => {
  9. // In a real implementation, this would throw if called during render
  10. const fn = handlerRef.current;
  11. return fn(...args);
  12. }, []);
  13. }

由于 useLayoutEffect 是在回溯期调用的,所以子节点的 useLayoutEffect 会先于父元素调用,所以如果子节点中需要通过 useLayoutEffect 获取 ref,此时的 ref 还没有更新,
所以需要一种时间点,在 useLayoutEffect 的回溯调用之前,能够改变 ref。
所以目前 useMemoizedFn 的方案是在 render 中更新 ref