React render array of components

Following up with my comment, you should be doing this instead:

{components.map((component, index) => (
    <span key={index}>
        { component }
    </span>
}

With React 16, you can use React.Fragment:

{components.map((component, index) => (
    <React.Fragment key={index}>
        { component }
    </React.Fragment>
}

If you’re always going to want to render all the components in your components file then you’re probably better off wrapping them in a React.Fragments tag.

Best practise is just to export this as a simple function that returns the components rather than as a constant.

So...

const Components = props => {
  return (
    <React.Fragment>

      <ComponentOne/>
      <ComponentTwo/>

    </React.Fragment>
  )
}

export default Components

That allows you to put multiple components next to each other without a DOM element containing them.

You should then just be able to render that by using it as a normal component and it’ll render all of them, so just import it then...

<Components />

Otherwise, if you want to treat them like an array, you have a function for free on the React object you’ve imported...

React.Children.toArray(arrayOfComponents)

You pass it an array of components (like in your original question) and it allows you to sort and slice it if you need to then you should be able to just drop it in the return of your render function


Have you consider using the new React Fragments? (in v16)

This would be the simplest solution as it would by pass the whole array/key issue.

If you need to pass key, then I'd suggest to simply require the components to have the keys. This is how React works, so I wouldn't suggest you to hide this behavior behind an interface that might not be predictable.

If you really need to do this, then you can use React.cloneElement to clone the element and inject new properties:

React.cloneElement(element, { key: 'foo' });

All of these answers are almost right. Just remove the <../> from your exports:

export default [
    ComponentOne,
    ComponentTwo,
]

And in the other file use .map():

export default class Dashboard extends React.Component {
    render = () => (
        <div className="tile is-parent">
            {components.map((Component, key) => (<Component key={key} />))}
        </div>
    )
}

Also note that if you wanted to use Fragment like others suggested you can just write <>...</> instead.

Tags:

Arrays

Reactjs