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

React Konva点击形状生成新形状报错:Uncaught TypeError问题排查

解决React + Konva点击形状渲染新形状的错误问题

嘿,我来帮你搞定这个报错!你遇到的Uncaught TypeError: events[i].handler.call is not a function错误,主要有两个原因,咱们一步步来修复:

1. 核心错误:onClick的赋值方式完全错了

你在Rectangle3的<Rect>里写了onClick={<Rectangle/>},这是问题的根源——Konva的onClick属性需要接收一个事件处理函数,而不是直接传一个JSX组件。当你点击这个矩形时,Konva会尝试调用你传给onClick的内容,但<Rectangle/>是个组件实例,不是函数,自然就报错了。

2. 次要错误:拖拽事件的语法问题

你的Rectangle组件里,onDragStart和onDragEnd的写法也不对:() => { isDragging: true } 这种写法在函数体里是无效的(看起来像是想写对象,但函数体里需要执行语句)。如果isDragging是组件的状态,你应该用this.setState来更新它。


修复后的完整代码示例

我们需要用一个父组件来管理要渲染的形状列表,通过点击事件触发添加新形状的逻辑:

第一步:修复Rectangle组件的拖拽逻辑

import React, { Component } from 'react';
import { Rect } from 'react-konva';

class Rectangle extends Component {
  constructor(props) {
    super(props);
    // 初始化拖拽状态
    this.state = {
      isDragging: false
    };
  }

  render() {
    // 假设blue是你定义好的颜色变量,否则直接用字符串"blue"
    return(
      <Rect
        x={250}
        y={25}
        width={50}
        height={100}
        stroke="black"
        draggable
        fill={blue}
        // 正确更新拖拽状态
        onDragStart={() => this.setState({ isDragging: true })}
        onDragEnd={() => this.setState({ isDragging: false })}
      />
    );
  }
}

第二步:重构Rectangle3和父组件,实现点击添加新形状

class Rectangle3 extends Component{
  render () {
    return(
      <Rect
        // 接收父组件传过来的点击处理函数
        onClick={this.props.onClick}
        x={380}
        y={85}
        width={100}
        height={50}
        stroke="black"
      />
    )
  }
}

// 父组件,管理所有要渲染的形状
class ShapeContainer extends Component {
  constructor(props) {
    super(props);
    this.state = {
      // 用数组存储新增的形状,每个形状要有唯一key
      additionalShapes: []
    };
  }

  // 点击Rectangle3时触发的函数,添加新形状到状态
  handleAddRectangle = () => {
    this.setState(prevState => ({
      additionalShapes: [...prevState.additionalShapes, { id: Date.now() }]
    }));
  };

  render() {
    return (
      <Stage width={window.innerWidth} height={window.innerHeight}>
        <Layer>
          {/* 可点击的触发矩形 */}
          <Rectangle3 onClick={this.handleAddRectangle} />
          {/* 渲染所有新增的Rectangle */}
          {this.state.additionalShapes.map(shape => (
            <Rectangle key={shape.id} />
          ))}
        </Layer>
      </Stage>
    );
  }
}

关键逻辑说明

  • 我们用父组件ShapeContainer的additionalShapes状态来追踪需要渲染的新形状,每次点击Rectangle3就往数组里加一个新项(用Date.now()做唯一id)。
  • Rectangle3只负责接收点击事件,把逻辑交给父组件处理,符合React的单向数据流原则。
  • 拖拽事件里正确使用this.setState来更新组件状态,避免语法错误。

内容的提问来源于stack exchange,提问作者N. Wilkins

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:29:15