react-konva中Stage内图形无法渲染问题求助
React-Konva图形无法显示问题排查
我使用react-konva的Stage组件渲染Rectangle等图形时,图形完全不显示,但react-konva-utils的Html组件能正常渲染HTML元素。控制台无报错信息,怀疑是refs使用导致问题,代码如下:
App.js
import "./App.css"; import { Stage, Layer, Rect, Circle } from "react-konva"; import { Html } from "react-konva-utils"; import { useEffect, useRef, useState } from "react"; import Elements from "./components/elements/elements.component"; function App() { const canRef = useRef(null); const canvasContainerRef = useRef(null); const [canvasHeight, setCanvasHeight] = useState(0); const [canvasWidth, setCanvasWidth] = useState(0); useEffect(() => { setCanvasWidth(canvasContainerRef.current.offsetWidt); setCanvasHeight(canvasContainerRef.current.offsetHeight); }, []); return ( <div className="app"> <div className="header"></div> <div className="main"> <div className="sidebar"></div> <div className="elements"> <Elements canvasRef={canRef} /> </div> <div className="editor"> <div ref={canvasContainerRef} className="canvas"> <Stage ref={canRef} width={canvasWidth} height={canvasHeight}> <Layer> <Html> <h1> testing</h1> </Html> <Rect x={20} y={50} width={100} height={100} fill="red" /> </Layer> </Stage> </div> <div className="slides"></div> </div> </div> </div> ); } export default App;
App.css
.app { display: flex; flex-direction: column; height: 100vh; width: 100%; } .header { display: flex; width: 100%; height: 8%; background-color: white; border-style: solid; } .main { display: flex; flex-direction: row; background-color: white; width: 100%; height: 92%; } .sidebar { display: flex; flex-direction: column; height: 100%; width: 6%; border-style: solid; background-color: white; } .elements { display: flex; background-color: white; width: 40%; max-width: 40%; } .editor { display: flex; flex-direction: column; width: 100%; height: 100%; } .canvas { display: flex; width: 100%; height: 80%; background-color: #ebf1ff; border-style: solid; } .slides { background-color: white; width: 100%; height: 20%; border-style: solid; }
问题根源与修复
核心拼写错误:
在useEffect中,你把offsetWidth拼写成了offsetWidt,导致canvasWidth始终为0。Stage宽度为0时,Konva绘制的图形无法显示(Html组件是独立于Canvas的DOM元素,不受Stage尺寸限制)。修正拼写即可解决基础问题:useEffect(() => { setCanvasWidth(canvasContainerRef.current.offsetWidth); setCanvasHeight(canvasContainerRef.current.offsetHeight); }, []);可选优化:自适应容器尺寸:
原代码仅在组件挂载时获取一次容器尺寸,若后续窗口或容器尺寸变化,Stage不会自适应。可以添加resize监听:useEffect(() => { const updateCanvasSize = () => { if (canvasContainerRef.current) { setCanvasWidth(canvasContainerRef.current.offsetWidth); setCanvasHeight(canvasContainerRef.current.offsetHeight); } }; updateCanvasSize(); window.addEventListener('resize', updateCanvasSize); return () => window.removeEventListener('resize', updateCanvasSize); }, []);可选优化:设置初始尺寸:
给canvasWidth和canvasHeight设置初始值,避免组件挂载瞬间Stage尺寸为0:const [canvasHeight, setCanvasHeight] = useState(window.innerHeight * 0.736); // 对应editor的80% * main的92% const [canvasWidth, setCanvasWidth] = useState(window.innerWidth * (1 - 0.06 - 0.4)); // 减去sidebar和elements的宽度占比
内容的提问来源于stack exchange,提问作者Aaeron
相关产品推荐
相关产品推荐

