目前我正在实现自己的一个组件库: 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} /> } 大家觉得哪种方案更好呢?
