Gatsby刷新页面报Cannot read properties of null (reading 'appendChild')错误如何解决
错误原因
- React函数组件的函数体代码执行时机早于JSX渲染到真实DOM的时机:你在return语句前执行
document.getElementById('container')时,你即将返回的<div id="container">还没有被插入到页面DOM树中,获取结果必然为null。 - 首次运行没有报错,通常是触发了客户端路由跳转或者开发环境热更新:上一次组件渲染遗留的
container节点还暂存在DOM中,所以能拿到对应元素;刷新页面时整个DOM树重建,没有遗留节点,就会直接抛出空指针错误。 - 额外说明:Gatsby本身具备SSG/SSR渲染特性,在服务端渲染阶段
document对象本身不存在,你这种直接在函数体操作DOM的写法本身也不符合React的设计规范。
修复方案
将DOM操作逻辑放到useEffect钩子中执行(useEffect会在组件挂载到真实DOM后触发),同时推荐用useRef绑定DOM节点,避免全局ID冲突问题,修复后代码如下:
import { useRef, useEffect } from 'react'; const Fun = () => { // 用ref绑定目标DOM节点,无需依赖全局ID const containerRef = useRef(null); const row = 15; const col = 15; useEffect(() => { const container = containerRef.current; // 空判断兜底,避免极端场景报错 if (!container) return; for(let i = 0; i < col; i++){ for(let j = 0; j < row; j++){ const circle = document.createElement('div'); container.appendChild(circle); } } // 可选:组件卸载时清空创建的节点,避免内存泄漏 return () => { container.innerHTML = ''; } }, []); // 空依赖数组代表仅在组件挂载时执行一次 return ( <div className={funWrapper}> <div ref={containerRef} className={funContainer}/> </div> ) }
内容的提问来源于stack exchange,提问作者Christopher Graham
相关产品推荐
相关产品推荐

