React组件内初始化Chessboard时getElementById获取元素为null如何解决?
问题原因
你当前的写法是在组件渲染流程执行时同步初始化棋盘,此时JSX对应的DOM节点还没有挂载到页面上,document.getElementById('board3')自然返回null,报错符合预期。return语句之后的代码永远不会执行,所以调整位置没用。
解决方案
方案1:使用useEffect钩子(最简单适配现有代码)
在函数组件内引入React的useEffect钩子,把初始化逻辑放在useEffect的回调里,空依赖数组表示仅在组件首次挂载完成后执行一次:
import { useEffect } from 'react'; export const MyPiece = props => { // 组件挂载完成后执行回调 useEffect(() => { new Chessboard(document.getElementById('board3'), { position: 'rn2k1r1/ppp1pp1p/3p2p1/5bn1/P7/2N2B2/1PPPPP2/2BNK1RR w Gkq - 4 11', orientation: COLOR.black, }); }, []); // 空依赖数组保证仅执行一次 return ( <> <DialogContent dividers> <Typography paragraph="true"> Some text </Typography> <Paper id="board3"></Paper> </DialogContent> </> ); };
方案2:结合useRef使用(更符合React最佳实践)
用ref绑定DOM节点,避免全局id可能带来的冲突问题,写法更规范:
import { useEffect, useRef } from 'react'; export const MyPiece = props => { // 创建ref存储DOM节点 const boardRef = useRef(null); useEffect(() => { // 直接从ref获取已经挂载的DOM节点 new Chessboard(boardRef.current, { position: 'rn2k1r1/ppp1pp1p/3p2p1/5bn1/P7/2N2B2/1PPPPP2/2BNK1RR w Gkq - 4 11', orientation: COLOR.black, }); }, []); return ( <> <DialogContent dividers> <Typography paragraph="true"> Some text </Typography> {/* 把ref绑定到Paper元素上 */} <Paper ref={boardRef}></Paper> </DialogContent> </> ); };
注意事项
如果你的Chessboard实例需要在组件卸载时销毁避免内存泄漏,可以在useEffect的返回函数里调用对应销毁方法,示例如下:
useEffect(() => { const board = new Chessboard(/* 初始化参数 */); return () => { board.destroy(); } }, []);
内容的提问来源于stack exchange,提问作者Jon
相关产品推荐
相关产品推荐

