React Hook 一些实践选择的讨论

2022-08-10 22:54:40 +08:00
 huijiewei

目前我正在实现自己的一个组件库: https://agile-ui.vercel.app/

里面用到了 useFocus, useHover 等等自定义的 Hook

目前这种机制的 Hook 有两种实现方式:

第一种: 传入原始的 onBlur, onFocus 事件,然后合并事件并返回 handle ,在组件里面使用 on 绑定:


export const useFocus = (options) => {
  const { state = false, onBlur, onFocus } = options;

  const [focus, setFocus] = useState(state);

  const handleBlur = useCallback(
    (e) => {
      setFocus(false);
      onBlur && onBlur(e);
    },
    [onBlur]
  );

  const handleFocus = useCallback(
    (e) => {
      setFocus(true);
      onFocus && onFocus(e);
    },
    [onFocus]
  );

  return { focus, handleBlur, handleFocus };
}

export const Demo = (props) => {
	const { onBlur, onFocus, ...rest } = props;
    
    const { focus, handleBlur, handleFocus } = useFocus({ onBlur, onFocus });
    
    return <button onBlur={handleBlur} onFocus={handleFocus} {...rest} />
}

第二种:利用 ref 绑定事件即可,不需要传递事件


export const useFocus = () => {
  const [focus, setFocus] = useState(false);
  const ref = useRef(null);
  const handleBlur = useCallback(() => setFocus(false), []);
  const handleFocus = useCallback(() => setFocus(true), []);

  useEffect(() => {
    if (ref.current) {
      ref.current.addEventListener('blur', handleBlur);
      ref.current.addEventListener('focus', handleFocus);

      return () => {
        ref.current?.removeEventListener('blur', handleBlur);
        ref.current?.removeEventListener('focus', handleFocus);
      };
    }

    return undefined;
  }, []);

  return { ref, focus };
}


export const Demo = (props) => {
    const { ref, focus } = useFocus();
    
    return <button ref={ref} {...props} />
}

大家觉得哪种方案更好呢?

2645 次点击
所在节点    React
7 条回复
XCFOX
2022-08-10 23:01:53 +08:00
ref ,并且这个 ref 得支持从外部传入。

如果返回 bind 绑定的话,可能会出现多个 hook 的 bind 对应到同一个 element 的同一个事件。
比如 useDrag() 和 useHover() 同时绑定了目标元素的 onMouseEnter 事件。
Leviathann
2022-08-10 23:31:10 +08:00
目前业内用的比较多的是 2
runtousa
2022-08-11 08:30:21 +08:00
文档写的挺好的
dog
2022-08-11 08:56:10 +08:00
可以看看 ahooks ,他们实现了很多自定义的 hook
https://github.com/alibaba/hooks
Mutoo
2022-08-11 09:48:34 +08:00
第一种更容易 compose handle functions ,如果用户需要额外的逻辑的话,第二种就没办法实现了。
huijiewei
2022-08-11 12:04:21 +08:00
感谢大家的回复。最终使用第二种方案,利用 useMergeRefs 的能力,合并 handle 也非常简单
juneszh
2022-08-11 12:31:33 +08:00
ref

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/872041

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX