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
相关产品推荐
相关产品推荐

