ben*_*a21 2 dom reactjs material-ui react-hooks
我试图在第一次加载组件时获取对 material-ui 对话框的 DOM 节点的引用,但该引用始终为undefined.
这是我的方法:
import React, { useEffect, useRef } from "react";
import {
Dialog,
DialogTitle,
DialogContent,
DialogContentText
} from "@material-ui/core";
export default function App() {
const dialogRef = useRef();
useEffect(() => {
console.log("Dialog Ref");
console.log(dialogRef.current);
}, []);
return (
<Dialog open ref={dialogRef}>
<DialogTitle>Ref Test Dialog</DialogTitle>
<DialogContent>
<DialogContentText>
Please check the console to see if a ref to this Dialog was logged.
</DialogContentText>
</DialogContent>
</Dialog>
);
}
Run Code Online (Sandbox Code Playgroud)
该材料UI对话框API文档指出,“裁判被转发到根元素,”和我的方法是基于阵营useRef文档,所以它看起来这应该是工作。
事实上,当我对一个<div>元素使用相同的方法时,它确实有效。我是否遗漏了什么,或者这是 Material UI 中的错误?
这是该问题的一个“工作”示例:
https://codesandbox.io/s/hopeful-agnesi-3i0p3?file=/src/App.js
Dialog利用 Modal,而Modal又利用 Portal。Material-UI 的 Portal 组件使用 React 的createPortal API在父组件的 DOM 层次结构之外渲染 Dialog。
的参数之一createPortal是要在其中呈现的 DOM 节点。Dialog 支持通过容器 prop控制这个 DOM 节点(默认为 document.body)。Material-UI在效果中获取容器的 DOM 节点,然后呈现 Dialog。
因此,在组件的初始渲染时,Material-UI 的 Portal 组件将识别容器并触发 Portal 组件的后续渲染,该渲染将实际渲染 Dialog。
您可以使用disablePortal 道具禁用此功能,在这种情况下,Dialog 将立即呈现,并且 ref 将按您的预期工作。
如果您想保留默认的门户行为,您可以将回调函数作为 ref 传递,以便在 ref 首次可用时执行代码。这样做时,重要的是要对收到的论点进行防御。每当引用发生变化时都会调用回调函数,其中包括在卸载期间将其改回 null。
还有一个onRendered 道具,您可以在其中放置此功能;但是文档表明它将在 v5 中被弃用和删除,并使用 ref 代替。
这是沙箱的修改版本,演示了使用 ref 的回调函数:
import React, { useEffect, useRef } from "react";
import {
Dialog,
DialogTitle,
DialogContent,
DialogContentText
} from "@material-ui/core";
export default function App() {
const dialogRef = useRef();
useEffect(() => {
console.log("Dialog Ref", dialogRef.current);
}, []);
return (
<Dialog
open
ref={(node) => {
dialogRef.current = node;
// Do your work requiring the node here, but make sure node isn't null.
console.log("ref function", node);
}}
onRendered={() => console.log("onRendered", dialogRef.current)}
onEntering={() => console.log("onEntering", dialogRef.current)}
onEntered={() => console.log("onEntered", dialogRef.current)}
>
<DialogTitle>Ref Test Dialog</DialogTitle>
<DialogContent>
<DialogContentText>
Please check the console to see if a ref to this Dialog was logged.
</DialogContentText>
</DialogContent>
</Dialog>
);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1025 次 |
| 最近记录: |