Snowman Snowman - 1 month ago 9
Javascript Question

Choosing react component's type at runtime in JSX

I have a react app in which I'd like to choose the type of component at runtime. I'm using ES6 and JSX.

Here's my code:

import Canvas from '../components/Canvas'
import CanvasTextbox from '../components/CanvasTextbox';


....

export default class CenterPane extends React.Component {

...

render() {
const canvasKids = [];

//for (var i = 0; i < 1; i++) {
// canvasKids.push(<CanvasTextbox key={i} id={'CanvasTextbox1'} />);
//};

for (var i = 0; i < 1; i++) {
let kid = this.state.kids[i];
let CanvasComp = kid.type; // evaluates to 'CanvasTextbox '
canvasKids.push(<CanvasComp key={i} id={kid.id} />);
console.log(canvasKids)
};



return (
<div>
Canvas:
<Canvas
name="myCanvas"
addChild={this.onAddChild.bind(this)}
>

{canvasKids}


</Canvas>
</div>

);
}

}


When I refer to the component by name, (as in the commented
for
loop), it works. However, if I try to use the name from a variable, it doesn't.

I tried assigning the name to a capitalized variable, as guided in the docs, but still nothing.

My canvas component indeed has the child, but it's not a react component, as seen in this react devtools screengrab:

enter image description here:

The component is not rendered on the canvas at all.

Please help. Thanks

Answer

Whatever you use as JSX "tag" has to resolve to a function (lowercase names representing HTML tags are the exception). If kid.type resolves to a string, then it doesn't work.

You'd have to build a name => component map first:

const components = {
  CanvasTextbox,
};

// ...

let CanvasComp = components[kid.type];
Comments