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

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;
}

问题根源与修复

  1. 核心拼写错误:
    在useEffect中,你把offsetWidth拼写成了offsetWidt,导致canvasWidth始终为0。Stage宽度为0时,Konva绘制的图形无法显示(Html组件是独立于Canvas的DOM元素,不受Stage尺寸限制)。修正拼写即可解决基础问题:

    useEffect(() => {
      setCanvasWidth(canvasContainerRef.current.offsetWidth);
      setCanvasHeight(canvasContainerRef.current.offsetHeight);
    }, []);
    
  2. 可选优化:自适应容器尺寸:
    原代码仅在组件挂载时获取一次容器尺寸,若后续窗口或容器尺寸变化,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);
    }, []);
    
  3. 可选优化:设置初始尺寸:
    给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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 07:05:24