1

我想在 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 没有 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>
    );
  }
}

所以我的问题是:在不知道它们的确切类型的情况下渲染对象的正确方法是什么?先感谢您。

4

2 回答 2

2

通常,您不应该将 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>
    );
  }
}
于 2020-03-21T17:35:22.060 回答
1

您可以使用 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>
        );
}
于 2020-10-27T10:46:30.130 回答