You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React新旧版本差异:createRoot渲染后canvas获取为null问题

问题原因及解决方案

核心差异:同步 vs 异步渲染

  • ReactDOM.render 是同步渲染:调用后会立即完成DOM的挂载与渲染,所以在它执行后直接查询canvas元素,能拿到已挂载的DOM节点。
  • createRoot 启用并发异步渲染(React 18+核心特性):渲染任务会被React调度,可能拆分或延后执行,不会阻塞主线程。如果在调用createRoot().render(<App />)后立刻查询DOM,此时React大概率还没完成canvas的挂载,因此返回null。

适配旧代码的问题

早期Excalidraw代码基于React同步渲染逻辑编写,可能存在同步依赖DOM挂载的逻辑(比如组件外部直接查询DOM、或在组件生命周期早期未等待渲染完成就获取元素)。createRoot的异步特性打破了这种同步依赖,导致获取DOM时元素未就绪。

正确的DOM获取方式

要在createRoot模式下正常获取canvas,需调整为React推荐的异步方式:

  • 使用Ref机制:在组件内定义const canvasRef = useRef(null),给canvas元素添加ref={canvasRef},然后在useEffect钩子中访问canvasRef.current——useEffect会在DOM更新完成后执行,此时能拿到已挂载的canvas。
  • 依赖生命周期钩子:如果是组件外部查询DOM,必须确保等待React完成渲染,比如将查询逻辑放在组件的useEffect中,而非直接在render调用后同步执行。

React官方说明核心要点

React 18文档明确了两者的关键区别:

  • ReactDOM.render 属于旧版同步API,在React 18中使用会进入兼容模式,不启用并发特性。
  • createRoot 是新版渲染入口,默认启用并发渲染,渲染过程异步,不能假设调用render后DOM会立即更新。
  • 所有依赖同步获取DOM的逻辑都需要调整为React钩子或生命周期方法,避免直接在render调用后同步查询DOM。

内容的提问来源于stack exchange,提问作者Deni Streltsov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 13:30:41