5

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?

4
  • yes, it's a string: Commented Sep 26, 2017 at 9:54
  • @brainstormtrooper Dont store string in item.type. Instead store component itself. Commented Sep 26, 2017 at 9:59
  • itemslist: [ { type: 'Foo', }, { type: 'Bar', }, { type: 'Baz', }, ] Commented Sep 26, 2017 at 9:59
  • @Prakashsharma, How can I do that? I have a config file in javascript... I need to be able to iterate and configure my components... Commented Sep 26, 2017 at 10:02

3 Answers 3

4

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} />);
});
Sign up to request clarification or add additional context in comments.

3 Comments

@brainstormtrooper I am not sure i got you. My point is that from string, you cannot render component. If you do not have component reference then just create a map object which map your string to component.
@brainstormtrooper See this github.com/facebook/react/issues/3365
0

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} />
});

Comments

0

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>
);

2 Comments

Thank you. I tried that, but I get the same result :-(
Are you string beginning with upperCase character, else it wont be treated as a react component

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.