UseEffect中的UseRef问题



示例是一个功能组件。我正在使用useRef()钩子来获取ref一个div元素。当示例装载时,我想事件侦听器附加到引用

const Example: React.FC = () => {
const ref = useRef<HTMLDivElement>(null);
const handleClick = (): void => {
// mouse click logic
};
useEffect(() => {
if (ref && ref.current) {
ref.current.addEventListener('click', handleClick);
}
return (): void => {
if (ref && ref.current) {
ref.current.removeEventListener('click', handleClick);
}
};
}, []);
return (
<div ref={ref} />
);
};

发生的情况是,当示例装入时,引用仍然为空。因此,我无法将event listener附加到它。替代解决方案是将id分配给div,并将事件侦听器直接附加到DOM节点,这不是我真正想做的。

关于如何将事件侦听器连接到引用的任何指导都将非常有用:(

您可以使用onClick来设置事件。

const Example = () => {
const handleClick = useCallback(() => {
// mouse click logic
}, [])
return (
<div onClick={handleClick}>Hello World</div>
);
};

但如果你想使用ref,你需要理解一些好的概念。首先,我测试了您的代码,当执行useEffect时,ref就准备好了,因为useEffect是在绘制DOM之后执行的。

其次,你需要了解钩子的依赖关系,因为在你的代码中,handleClick是在每个渲染中创建的,但useEffect使用的是这个函数创建的第一个引用,所以如果你在handleClick中使用依赖关系,你可能会遇到问题

最后,我建议您投资useCallback, useState, useRef, useEffectuseReducer,以了解每种情况的差异和最佳情况。

您不需要ref。React使用标准声明性语法支持开箱即用的点击事件。

const Example: React.FC = () => {
const ref = useRef<HTMLDivElement>(null);
const handleClick = (): void => {
// mouse click logic
};
return (
<div onClick={handleClick} />
);
};

你在评论中提到,你尝试这样做的原因是为了让lint规则静音。但是,使用ref并不能解决linter指出的问题,它只会使代码变得足够复杂,以至于linter无法弄清楚你在做什么,因此没有意识到你的代码和以前有同样的问题。

要解决lint问题,请在div中添加一个role属性,这样屏幕阅读器就可以知道这个div的用途。具体使用哪个角色取决于点击处理程序在做什么,但最可能的角色可能是"按钮"或"链接"。

return (
<div onClick={handleClick} role="button" />
);

最新更新