"Cannot read properties of null (reading 'appendChild')" gatsby 中的错误仅在站点刷新时显示

"Cannot read properties of null (reading 'appendChild')" error in gatsby shows only on site refresh

我正在使用 gatsby develop,当我为我的一个组件输入此代码时,它会运行 fin 并创建 div,但是当我刷新页面时,它会提示错误“无法读取 null 的属性(读取 'appendChild')' 用于行 'container.appendChild(circle);'。为什么只有在我刷新页面时才会出现这个问题,我该如何解决这个问题?

const Fun = () => {
    const container = document.getElementById('container');
    let row = 15;
    let col = 15;

    for(let i = 0; i < col; i++){
        for(let j = 0; j < row; j++){
            const circle = document.createElement('div');
            container.appendChild(circle);
        }
    }

    return (
        <div className={funWrapper}>
            <div id={'container'} className={funContainer}/>
        </div>
    )
}

您正在使用 React(因此使用 Gatsby)创建和操作 virtual DOM (vDOM),而您的代码指向并操作真实的 DOM(因为使用 document)。

React 不知道其范围之外的变化,反之亦然,因此它永远不会知道真实 DOM 中的变化,就像您正在做的那样。

在您的情况下,因此,容器在您尝试请求它时可能存在也可能不存在(因为刷新)。

您可以利用 useRef hook 在虚拟 DOM 中创建对元素的引用,从而在 React 范围内创建完全相同的行为。

const Fun = () => {
  const container = useRef(null);

    useEffect(()=>{
      container.current.appendChild('<div>a circle</div>')
    }, [])

   
    return (
        <div className={funWrapper}>
            <div id={'container'} ref={container} className={funContainer}/>
        </div>
    )
}

想法是等待 React 的生命周期,直到加载 DOM 树,这就是 useEffect 和空 deps ([]) 所做的。您可以尝试在其中添加以前的内容,但您将破坏我之前提到的 vDOM-DOM 范围,尽管它可能有效。

如您所见,container.current 包含您的 <div> 的引用,并保留与 document.getElementById.

完全相同的信息