I'm trying to render an array of named react components, say <Foo />
, <Bar />
, and <Baz />
,for example.
const rendered = [];
const getItems = this.props.itemslist.map((item, key) => {
const TYPE = item.type;
rendered.push(<TYPE data-attributes={attributes} key={key} />);
});
return (
<Grid>
<Row>
{rendered}
</Row>
</Grid>
);
I can iterate over my array and see in the console the array of elements, but they are rendered as empty html elements "<foo></foo><bar></bar><baz></baz>
", and not the actual components.
Why is this happening and, more importantly, how can I get the COMPONENTS to render?
You should use component instead of string in item.type
like this
import Foo from './Foo';
import Bar from './Bar';
[ { type: Foo, }, { type: Bar, }, { type: Baz}]
UPDATE:
If you do not have component reference in advance then use a mapping object which convert your string to component reference like this
import Foo from './Foo';
import Bar from './Bar';
const mapper = {
Foo: Foo,
Bar: Bar,
}
// Then use it like this
const getItems = this.props.itemslist.map((item, key) => {
const Type = mapper[item.type];
rendered.push(<Type data-attributes={attributes} key={key} />);
});
The first mistake is see if an incorrect use of .map
. Remember that .map
traverses each array element and changes them. Right now, you are using it as if it were .forEach
.
Your code should look more like this:
const getItems = this.props.itemslist.map((item, key) => {
const TYPE = item.type;
return <TYPE data-attributes={attributes} key={key} />
});
You can use React.createElement
for creating the React element with a dynamic name. Also make sure to import those components.
const rendered = [];
const getItems = this.props.itemslist.map((item, key) => {
const component = React.createElement(item.type, {data-attributes: attributes, key: key}, null);
rendered.push(component);
});
return (
<Grid>
<Row>
{rendered}
</Row>
</Grid>
);