使用 KonvaJs-ReactJs 动态渲染对象

Rendering objects dynamically with KonvaJs-ReactJs

我想在 KonvaJs 的帮助下渲染一组 React 组件,但不知道我在特定时刻绘制了哪个对象。更具体地说,这是我的代码:

我要渲染的React组件之一,wall.js:

class CWall extends React.Component {
 render() {
    return (
      <React.Fragment>
        <Rect /*some props*/></Rect>
        <Transformer /*some props*/></Transformer>
      </React.Fragment>
    )
  }
}

在另一个组件中,我在单击按钮时创建了 CWall,planmenu.js:

class PlanMenu extends React.Component {
  render() {
    ...
    return (
    ...
        <button type="button"
          onClick={() => { addObject(
            new CWall({
                x: 100,
                y: 100,
                length: 200
            }))}}>Wall
        </button>
    )
  }
}

创建的对象被传递给应该显示它们的组件,planbuilder.js:

import CWall from './objects/wall'

class PlanBuilder extends React.Component {
  render() {
    const { objects } = this.props
    return (
      <Stage>
        <Layer>
          {
            objects.map(function(object) {
              var ObjectType = object.constructor.name;
              /* the following line gives an error to me */
              return <ObjectType {...object.props} key={object.id} />;
            }, this)
          }
        </Layer>
      </Stage>
    );
  }
}

指定行抛出错误:

konva has no node with the type CWall

但是,如果我直接渲染一个 CWall,我会按预期将其显示在屏幕上。在我看来,这似乎是 konva 能够渲染 CWall 对象的证据:

class PlanBuilder extends React.Component {
  render() {
    const { objects } = this.props
    return (
      <Stage>
        <Layer>
          <CWall x={100} y={100} length={200} />
        </Layer>
      </Stage>
    );
  }
}

所以我的问题是:在不知道确切类型的情况下渲染对象的正确方法是什么? 提前谢谢你。

一般来说,你不应该将 React 组件直接添加到状态中。相反,只需添加有关您的应用程序的纯数据,然后只从该数据进行渲染。可以是这样的:

class PlanMenu extends React.Component {
  render() {
    ...
    return (
    ...
        <button type="button"
          onClick={() => { addObject({ x: 10, y: 10, type: 'wall' })}}
        </button>
    )
  }
}


import CWall from './objects/wall'


const TYPES = {
   'wall' : CWall
};

class PlanBuilder extends React.Component {
  render() {
    const { objects } = this.props
    return (
      <Stage>
        <Layer>
          {
            objects.map(function(object) {
              const Component = TYPES[object.type];
              return <Component {...object} key={object.id} />;
            }, this)
          }
        </Layer>
      </Stage>
    );
  }
}

您可以使用 JSX.Element 的数组,当单击按钮时,您将创建 JSX.Element 并将其推送到 JSX.Element 的数组,然后将数组放入渲染中,例如

<button type="button"
    onClick={() => { addObject(
    <CWall
        x: 100,
        y: 100,
        length: 200
    />)}
</button>
render() {
    const { objects } = this.props
        return (
            <Stage>
                <Layer>
                    {objects}
                </Layer>
            </Stage>
        );
}