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

