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

React TypeScript中Canvas无法填充蓝色问题及修复方案

React Canvas无法填充蓝色的问题解决

嘿,我来帮你理清楚这个问题!你的代码里的核心问题其实是React组件的渲染时机和useRef的绑定时机不匹配。

在组件第一次执行函数体的时候,<canvas>元素还没被React挂载到DOM树上呢!这时候canvasRef.current自然是null,所以你写的那两段console.log('this never prints!!')根本不会执行,填充蓝色的逻辑也就没机会跑起来。

咱们来捋一捋原代码的执行顺序:

  • 组件函数开始运行,初始化canvasRef,此时current属性是null
  • 你打印canvasRef.current,输出null,然后跳过if (canvasRef.current)里面的所有逻辑
  • 组件返回JSX,React开始把<canvas>元素挂载到DOM上,这时候canvasRef.current才会被赋值为对应的Canvas DOM节点

解决这个问题的关键就是把Canvas的绘制逻辑放到useEffect里——因为useEffect的回调函数会在DOM挂载完成后执行,这时候canvasRef.current已经有值了。

下面是修正后的完整代码:

import React, { useRef, useEffect } from 'react';

const App: React.FC = () => {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const canvasWidth = 820;
  const canvasHeight = 620;

  useEffect(() => {
    // 先确认ref已经绑定到DOM元素
    if (canvasRef.current) {
      const canvas = canvasRef.current;
      const ctx = canvas.getContext('2d');
      
      if (ctx) {
        // 这里要注意:先设置canvas的宽高,再绘制!
        // 因为设置宽高会重置画布,先绘制的话内容会被清空
        canvas.width = canvasWidth;
        canvas.height = canvasHeight;
        
        ctx.fillStyle = 'blue';
        ctx.fillRect(0, 0, canvasWidth, canvasHeight);
      }
    }
  }, []); // 空依赖数组确保这个effect只在组件首次挂载时执行一次

  return (
    <canvas ref={canvasRef} width={canvasWidth} height={canvasHeight} />
  );
};

export { App };

另外还要提个小细节:原代码里是先调用fillRect再设置canvas.width和canvas.height,这其实会导致绘制的内容被清空——因为修改Canvas的宽高会重置整个画布的状态,所以一定要先设置宽高,再执行绘制操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 14:27:28