[英]Why is an element found using getElementById in Next.js returning null even when document is defined?
Using SSR in my React/Next app.在我的 React/Next 应用程序中使用 SSR。
Trying to find an element with the id but is returning null尝试查找具有 id 但返回 null 的元素
even when document is present (and I can see the div with the id plTable),即使存在文档(我可以看到带有 id plTable 的 div),
and even when getElementById is called after 6 seconds to ensure the element has been loaded on screen.甚至在 6 秒后调用 getElementById 以确保元素已加载到屏幕上。
What is the issue and how can I fix this?问题是什么,我该如何解决?
Here is the component:这是组件:
const LineItemTable: React.FC<LineItemTableProps> = ({ reportName }) => {
const classes = useStyles({});
const dispatch = useDispatch();
const [page, setPage] = useState<number>(0);
const selectedCompanyId = useSelector((state) => state.company.selectedId);
const company = useSelector((state) => state.company.current);
useEffect(() => {
if (reportName && selectedCompanyId) {
dispatch(
getReportByName({
name: reportName, // 'profit and loss' or 'balance sheet'
includeLineItems: true,
page: page,
}),
);
}
}, [reportName, selectedCompanyId]);
let plTable: any = 'kk';
useEffect(() => {
console.log('uef');
if (typeof document !== 'undefined') {
setTimeout(() => {
plTable = document.querySelector('plTable');// ***** NEVER FOUND ******
console.log('doc', document); // ***** is found and defined correctly *****
console.log('plTable', plTable); // ***** null *****
}, 6000);
}
});
const endObserver = new IntersectionObserver(
(entries) => {
const [entry] = entries;
if (!entry.isIntersecting) {
//Put what you want to happen if the end is NOT visible
console.log('not visible');
} else {
//Put what you want to happen if the end is visible
//For instance firing your function
// setPage(page + 1);
console.log('visible');
}
},
{ root: null, threshold: 1 },
);
// endObserver.observe(plTable);
const getLineItems = useMemo(() => makeGetAllLineItemsByReport(reportName), [
reportName,
]);
const lineItems = useSelector((state) => getLineItems(state));
if (!lineItems) return null;
// ADDED
// Add an elemnt in your html with the class of "end" at the end of the chart
// I recommend adding an empty div with the class of "end" and setting it's opacity to 0
return (
<div
id="plTable" // ****** Defined here *******
style={{
display: 'flex',
alignItems: 'flex-end',
margin: 'auto 0px',
}}
>
<Grid container spacing={3}>
<Grid item xs={12}>
<Card
sx={{
padding: '20px',
}}
>
<CardContent
sx={{
alignItems: 'center',
display: 'flex',
height: '1000px',
}}
>
<Scrollbar className={classes.scrollBar}>
<Table className={classes.root}>
<TableHead>
<TableRow>
<th>
<TableCell className={classes.headerStyle}>
ANALYSIS CATEGORY
</TableCell>
<TableCell
className={classes.headerStyle}
sx={{ marginRight: '10px' }}
>
NAME
</TableCell>
{company &&
company.dates.map((header) => (
<TableCell
className={classes.headerStyle}
sx={{
width: '200px !important',
marginLeft: '10px',
}}
key={header}
>
{header}
</TableCell>
))}
</th>
</TableRow>
</TableHead>
<TableBody>
{lineItems.map((lineItem, i) => (
<TableRow key={lineItem.id}>
<LineItemRow
i={i}
id={lineItem.id}
reportName={reportName}
level={lineItem.level}
/>
</TableRow>
))}
</TableBody>
</Table>
</Scrollbar>
</CardContent>
</Card>
</Grid>
</Grid>
</div>
);
};
According to MDN docs, querySelector
either takes an element to look for:根据 MDN 文档, querySelector
需要一个元素来查找:
querySelector('plTable')
/* Looking for html tag plTable */
or an identifier:或标识符:
querySelector('#plTable')
/* Looking for an element with id of plTable */
Don't use DOM selectors in React, use refs
to access DOM nodes.不要在 React 中使用 DOM 选择器,使用refs
访问 DOM 节点。 You can create a ref with useRef
or React.createRef
or you can pass a callback to the ref
attribute of an element, that will receive the DOM node reference when the virtual DOM has done with the reconciliation.您可以使用useRef
或React.createRef
创建一个 ref,或者您可以将回调传递给元素的ref
属性,当虚拟 DOM 完成协调后,它将接收 DOM 节点引用。
To check if the node is mounted and do something with it being sure it is mounted, try this:要检查节点是否已挂载并对其执行某些操作以确保已挂载,请尝试以下操作:
<div
id="plTable" // ****** Defined here *******
style={{
display: 'flex',
alignItems: 'flex-end',
margin: 'auto 0px',
}}
ref={node => {
if (node) console.log("p1Table", node)
//Do something with node
}}
>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.