React中Canvas图片不显示,是否与useEffect执行时机有关?
问题原因
核心问题是组件挂载时图片还未加载完成,就调用了drawImage方法。
你的useEffect依赖为空数组,只会在组件首次挂载时执行一次。此时imageRef.current虽然指向了img元素,但图片资源可能还在网络请求中,还没完成加载。drawImage方法对未加载完成的图片不会产生任何绘制效果,所以Canvas始终为空。
修改useEffect依赖后能显示,是因为修改依赖触发了useEffect重新执行,这时候图片已经加载完成了,所以drawImage能正常工作;但刷新页面后组件重新挂载,又回到了图片未加载就执行绘制的状态,因此再次空白。
解决方案
要确保图片加载完成后再执行Canvas绘制,有两种常见方式:
方式一:监听图片的load事件
直接在img元素上绑定onLoad事件,图片加载完成后触发绘制逻辑:
const Testing = () => { const canvasRef = useRef(null) const imageRef = useRef(null) const drawImageToCanvas = () => { const image = imageRef.current const canvas = canvasRef.current if (!image || !canvas) return canvas.width = 100 canvas.height = 100 const context = canvas.getContext('2d') context.drawImage(image, 0, 0, canvas.width, canvas.height) } return ( <> <img src={image} alt="" className={styles.theImage} ref={imageRef} onLoad={drawImageToCanvas} /> <canvas className={styles.canvasCont} ref={canvasRef}></canvas> </> ) }
方式二:在useEffect中绑定load事件
如果需要在useEffect里处理,可给图片绑定load事件,确保加载完成后再绘制:
const Testing = () => { const canvasRef = useRef(null) const imageRef = useRef(null) useEffect(() => { const image = imageRef.current const canvas = canvasRef.current if (!image || !canvas) return const draw = () => { canvas.width = 100 canvas.height = 100 const context = canvas.getContext('2d') context.drawImage(image, 0, 0, canvas.width, canvas.height) } // 检查图片是否已加载完成 if (image.complete) { draw() } else { // 未加载完成则绑定load事件 image.addEventListener('load', draw) // 清理函数,防止内存泄漏 return () => image.removeEventListener('load', draw) } }, []) return ( <> <img src={image} alt="" className={styles.theImage} ref={imageRef} /> <canvas className={styles.canvasCont} ref={canvasRef}></canvas> </> ) }
另外注意:你的代码中img的src={image},要确保image变量是正确的图片路径或导入的图片资源,否则图片本身加载失败也会导致Canvas空白。
内容的提问来源于stack exchange,提问作者Hadi Zouhbi
相关产品推荐
相关产品推荐

