I want to render an array of React components with the help of KonvaJs without knowing exactly which object I draw at a particular moment. To be more specific, here is my code:
One of the React components I want to render, wall.js:
class CWall extends React.Component {
render() {
return (
<React.Fragment>
<Rect /*some props*/></Rect>
<Transformer /*some props*/></Transformer>
</React.Fragment>
)
}
}
In the other component I create CWall when the button is clicked, planmenu.js:
class PlanMenu extends React.Component {
render() {
...
return (
...
<button type="button"
onClick={() => { addObject(
new CWall({
x: 100,
y: 100,
length: 200
}))}}>Wall
</button>
)
}
}
The created objects are passed to the component which should display them, 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>
);
}
}
The specified line throws an error:
konva has no node with the type CWall
However, if I render one CWall directly, I get it on the screen as expected. It seems to me like evidence that konva is able to render CWall objects:
class PlanBuilder extends React.Component {
render() {
const { objects } = this.props
return (
<Stage>
<Layer>
<CWall x={100} y={100} length={200} />
</Layer>
</Stage>
);
}
}
So my question is: what is the proper way of rendering objects without knowing their exact types? Thank you in advance.
In general, you should not add React components directly into the state. Instead, just add pure data about your app, and then just render from that data. It can be like this:
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>
);
}
}