UseEffect 中的 UseRef 问题
Posted
技术标签:
【中文标题】UseEffect 中的 UseRef 问题【英文标题】:UseRef issue in UseEffect 【发布时间】:2020-08-09 02:59:35 【问题描述】:示例是一个功能组件。我正在使用useRef()
挂钩来获取 ref 一个 div 元素。我想在 Example 挂载时附加一个事件监听器到 ref。
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 />
);
;
发生的情况是 ref 在 Example 确实挂载时仍然为空。因此,我无法将event listener
附加到它。 替代解决方案是将id
分配给 div 并将事件侦听器直接附加到 DOM 节点我不想真的想要这样做。
任何关于如何将事件侦听器附加到 ref 的指导都会非常有帮助:)
【问题讨论】:
使用ref添加点击监听的原因是什么?onClick
道具不够吗?
你使用的方式是正确的。添加一个有效的 sn-p:stackblitz.com/edit/react-kkqwwd 你可以为你遇到的问题创建一个演示吗?
@NicholasTower 因为将 onClick 属性传递给非交互式元素并不是一个好习惯。
because it's not a good practice to pass onClick prop to non-interactive elements.
说谁? Refs 是那些无法以声明方式做出反应的事情的逃生口。但是 react can 声明式地点击监听器,所以你应该这样做。
@NicholasTower 你可以在这里查看:github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/…
【参考方案1】:
您可以使用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, useEffect
和useReducer
以了解各自的差异和最佳情况。
【讨论】:
【参考方案2】:您不需要为此提供参考。 React 使用标准的声明式语法支持开箱即用的点击事件。
const Example: React.FC = () =>
const ref = useRef<HTMLDivElement>(null);
const handleClick = (): void =>
// mouse click logic
;
return (
<div onClick=handleClick />
);
;
您在 cmets 中提到您尝试这样做的原因是为了使 lint 规则保持沉默。但是使用 ref 并不能解决 linter 指出的问题,它只会使代码变得足够复杂,以至于 linter 无法弄清楚您在做什么,因此没有意识到您的代码具有相同的问题和以前一样。
要解决 lint 问题,请将角色属性添加到 div,以便屏幕阅读器知道此 div 的用途。具体使用哪个角色取决于点击处理程序正在做什么,但最可能的角色可能是“按钮”或“链接”。
return (
<div onClick=handleClick role="button" />
);
【讨论】:
感谢您分享这些信息。你能帮我吗:***.com/questions/61428958/… ?以上是关于UseEffect 中的 UseRef 问题的主要内容,如果未能解决你的问题,请参考以下文章
ZF_react hooks useEffect的实现 useRef useImperativeHandle的实现,react整体功能实现完毕
反应 useRef / useEffect HTMLCanvasElement 不可分配
如何在 UseEffect 中将事件侦听器添加到 UseRefs
使用 useeffect 和 useref TypeError 时出错:无法读取 null 的属性“getBoundingClientRect”