React useHover 钩子:如何优雅地处理元素悬停状态?
在 Web 应用开发中,处理元素的悬停状态是一个常见需求,用于实现交互式界面元素、工具提示等功能。useHover
钩子提供了一种简洁而有效的方式来在 React 组件中监听和响应元素的悬停状态。这个自定义钩子不仅简化了悬停状态的管理,还提供了一个声明式的 API 来处理鼠标悬停事件。以下是如何实现和使用这个自定义钩子:
const useHover = () => {
const [isHovering, setIsHovering] = React.useState(false);
const handleMouseOver = React.useCallback(() => setIsHovering(true), []);
const handleMouseOut = React.useCallback(() => setIsHovering(false), []);
const nodeRef = React.useRef();
const callbackRef = React.useCallback(
node => {
if (nodeRef.current) {
nodeRef.current.removeEventListener('mouseover', handleMouseOver);
nodeRef.current.removeEventListener('mouseout', handleMouseOut);
}
nodeRef.current = node;
if (nodeRef.current) {
nodeRef.current.addEventListener('mouseover', handleMouseOver);
nodeRef.current.addEventListener('mouseout', handleMouseOut);
}
},
[handleMouseOver, handleMouseOut]
);
return [callbackRef, isHovering];
};
const MyApp = () => {
const [hoverRef, isHovering] = useHover();
return <div ref={hoverRef}>{isHovering ? 'Hovering' : 'Not hovering'}</div>;
};
ReactDOM.createRoot(document.getElementById('root')).render(
<MyApp />
);
这个技巧的关键点包括:
使用
useState
来跟踪元素的悬停状态。定义
handleMouseOver
和handleMouseOut
回调函数来更新悬停状态。使用
useRef
和useCallback
来管理对目标元素的引用和事件监听器。返回一个回调 ref 和当前的悬停状态。