javascript - 使用 useRef 聚焦元素,将类迁移到 hooks 问题?
问题描述
有谁知道如何使用反应挂钩传递回调引用的正确方法。我正在尝试将内置在类组件中的模态转换为钩子组件,但我不确定正确的方法是什么。
onOpen = () => {
this.setState({ isOpen: true }, () => {
// Ref for the button
this.closeButtonNode.focus();
});
this.toggleScrollLock();
};
这就是我在代码中传递引用的方式
<ModalContent
buttonRef={(n) => {
this.closeButtonNode = n;
}}
{// More props...}
/>
并且模态内容组件具有这样的buttonRef
<button
type="button"
className="close"
aria-labelledby="close-modal"
onClick={onClose}
ref={buttonRef}
>
<span aria-hidden="true">×</span>
</button>
因此,当模式弹出时,我能够通过钩子将焦点集中在我的按钮关闭上,我设法复制行为的唯一方法是添加一个 useEffect 钩子来监听 isOpen 状态,如下所示:
useEffect(() => {
if (isOpen) closeButtonNode.current.focus();
}, [isOpen]);
const onOpen = () => {
setIsOpen(true);
toggleScrollLock();
};
这就是我传递道具的方式
const closeButtonNode = useRef(null);
return (
<ModalContent
buttonRef={closeButtonNode}
{// More props...}
/>
)
而且我只是像普通的 ref 一样使用它,没有传递回调函数,这是可行的,但我想知道为什么它会这样工作,以及为什么我不能像基于类的组件那样将焦点设置在 onOpen 函数上。
如果您想检查完整代码,这是沙箱。 https://codesandbox.io/s/hooks-modal-vs-class-modal-bdjf0
解决方案
为什么我不能
onOpen
像基于类的组件那样将焦点放在功能上
因为当onOpen
函数open
仍然被调用时false
,它会在模式已经打开后更新。请注意,useState没有第二个参数(回调),就像setState
您在基于类的组件中设置焦点时所做的那样。这就是为什么你需要使用useEffect
.
您可以通过设置延迟使用setTimeout
after 你设置open
为 true 来测试它,如下所示:
const onOpen = () => {
setIsOpen(true);
setTimeout(() => closeButtonNode.current.focus())
};
虽然,您使用的方法useEffect
可能是更好的选择。
代码沙盒示例。
推荐阅读
- javascript - 实现设备指纹的网络源
- django - Django REST框架中的文件上传处理
- java - 如何在java中使用用户输入添加2个可变长度数组
- swiftui - space around top of the background image
- sql-server - 如何编写查询以将 SQL Server 数据库模式从 Recovery 更改为 NoRecovery
- reactjs - 将道具传递给顶级组件中的状态
- json - 解组到 map[string]interface{} 后对 ma[string][]string 的类型断言失败
- deployment - 使用自动化脚本将多个 SSIS 包部署到 MSDB
- spring-boot - Mustache 不适用于 @RestController 但适用于 @Controller
- java - Java Swing 在线程“AWT-EventQueue-0”中读取 PDF 返回异常 java.lang.NoClassDefFoundError: org/bouncycastle/asn1/ASN1OctetString