Blog / React

How to render an array of components in React

How to render an array of components in React

This post is about how to render an array of components in react. On top of the normal cases, it also covers what to do if you don't have a key prop

Will MaygerWill Mayger
July 14, 2021
Article

We have an array of components, but now we need to find out how we can render them into React.

This post will go over everything you need to know for how to render an array of components in React.

There are a few different ways we can go about doing this in React and we will cover them all here.

If you are looking for how to render an array of components that don’t have keys, feel free to skip to the end of this article where this topic is explained.

How to render an array of components in React

How to render an array of components in React graphic

To render an array of components in React you simply need to pass the array into JSX by wrapping it in curly braces, just be sure that your components each have a unique key prop because React will use this when rendering it to avoid bugs.

Here is an example of rendering an array of objects in React:

export default function MyExampleComponent() {
 const componentArray = [
 <p key="example-key-1">Hello World</p>,
 <p key="example-key-2">Hello World</p>,
 ];

 return (
   <div>
     {componentArray}
   </div>
 );
}

Rendering an array of components with Array.prototype.map()

One of the most common ways (probably the most common way) of rendering an array of components in React is by making use of the Array.prototype.map function which looks like [].map() when being used.

The Array.prototype.map function will iterate (loop) over an existing array and return a new array based on a callback function that you provide.

[1, 2, 3].map(callbackFunction);

The callback function will be given the current array item, the index, and the entire array as arguments.

[1, 2, 3].map((arrayItem, arrayItemIndex, wholeArray) => {});

You can use this data to return a new value from your function which Array.prototype.map will then use to add into a new array in the same position/index.

For example:

const oldArray = [1, 2, 3]; // [1, 2 ,3]
const newArray = oldArray.map(
  (arrayItem, arrayItemIndex, wholeArray) => arrayItem * 10
); // [10, 20, 30];

// oldArray will be the same - [1, 2, 3]
// newArray will be [10, 20, 30]

In this example, we are multiplying the existing value in our callback by 10 and then returning that value.

By doing this Array.prototype.map will return a new array where each of the numbers have been multiplied by 10.

So how can we apply this to an array of React components?

In this situation, we could be using Array.prototype.map to create the array of components from an array of data inside of our JSX.

For example, if we have the following array of objects:

const exampleArray = [
  {name: 'John', birthday: '25/12/1990', id: '123'},
  {name: 'Abby', birthday: '22/10/1991', id: '124'},
];

We can now use this array to create an array of components that gets directly rendered within our JSX like so:

const birthdayArray = [
  {name: 'John', birthday: '25/12/1990', id: '123'},
  {name: 'Abby', birthday: '22/10/1991', id: '124'},
];

export default function Birthdays() {
  return (
    <div>
      {birthdayArray.map(({ name, birthday, id }) => (
        <p key={id}> {name}'s birthday is on {birthday} </p>
      ))}
    </div>
  );
}
rendered an array of components in React example

In the above example, we are using Array.prototype.map to transform the array of objects into an array of components/elements that React can then directly use to render them because we are passing it straight into the JSX.

You may notice that we are adding in a “key” prop in the above example and setting it as the id.

This is because whenever you render an array of components in React it is important to add in the key with a unique identifier local to that array so that React can track these items between renders and prevent bugs in your application.

Rendering an array of components with a variable

Rendering an array of components stored as a variable is pretty easy for us to do and will be done in the same way as above.

The only difference will be that we don’t need to transform the array with Array.prototype.map because it is already an array of components.

So to render an existing array of components all we need to do is pass it into the JSX with curly braces like in this example:

const birthdayComponentArray = [
  <p key="123"> John's birthday is on 25/12/1990 </p>,
  <p key="124"> Abby's birthday is on 22/10/1991 </p>,
];

export default function Birthdays() {
  return (
    <div>
      {birthdayComponentArray}
    </div>
  );
}

Once again, you should take notice of how the key has still been applied here to each component in the array because the same rules apply because we are still passing an array of components into the JSX of our React component.

Rendering an array of components with a React fragment

A react fragment is a way of wrapping/grouping components or elements together so that they can live and act as a single component.

This is needed whenever you can only have one child or parent node in a component, for example when we return a React component there can only be one parent element returned, and if we don’t need a physical element like a div then we could instead use a fragment.

To do this we can either use <React.Fragment></ React.Fragment> or <></>.

To apply this to rendering an array of components in React, all we need to do is wrap our array in a fragment.

When in use here is an example of how the fragment will look wrapping our array of components:

const birthdayArray = [
  {name: 'John', birthday: '25/12/1990', id: '123'},
  {name: 'Abby', birthday: '22/10/1991', id: '124'},
];

export default function Birthdays() {
  return (
    <>
      {birthdayArray.map(({ name, birthday, id }) => (
        <p key={id}> {name}'s birthday is on {birthday} </p>
      ))}
    </>
  );
}

Rendering an array of components that don’t have keys

The last topic to look at when rendering an array of components is if you are ever in the situation where you already have an array of components but they don’t have a key and you can’t modify them for one reason or another, maybe they are passed down as a prop and you don’t have access to them.

Firstly, if you are in this situation, it might be worth looking into why this approach is needed because for the most part you shouldn’t have to pass arrays of components around your application.

It is better to pass data around in your application via props or a context, and then transform the data into an array of components only when you need to in order to render it, not to pass components around like this.

If you really can’t avoid this, then firstly, I would suggest trying to find the source of the component array and adding in the key directly into it by making the component callable with a key like so:

[({ key }) => <SomeComponent key={key} />]

Or by adding it in directly:

[<SomeComponent key="123" />]

If neither of these approaches are applicable in your situation, then instead you can try to wrap the component in a React fragment, element, or clone the element method React.cloneElement.

To wrap with a fragment or element you would need to use the Array.prototype.map method to transform your array of components into an array of new components that accept a key like so:

[
  <p>Hello World</p>,
  <p>Hello World</p>,
].map((component, index) => (
  <React.Fragment key={index}>
    {component}
  </React.Fragment>
))

For an element instead of a fragment, just replace React.Fragment with the element of your choosing.

To use React.cloneElement to solve this issue we need to use the Array.prototype.map function once again to transform our array and replace the components.

React.cloneElement will let us provide a component or element and then add additional properties into it.

To use it we just need to return it from our callback like so:

[
  <p>Hello World</p>,
  <p>Hello World</p>,
].map(
  (component, index) => React.cloneElement(component, { key: index })
);

Now in the official React docs about keys it does warn against using the index as the key, and this is because if the order of the array ever changes it will cause bugs whenever re-rendering the array.

However, it also does mention that you can use them as a last resort, and in this situation that is what we would be doing.

If you use the index as a key, you need to make sure the order of the array does not change.

Summary

And there we have how to render an array of components in React.

To summarise which ones to use, wherever possible use Array.prototype.map to create an array of components with keys from data directly from data in JSX or storing as a variable and then passing it into your JSX from data.

Only look into rendering an array of components that don’t have keys as a last resort.

Foxi - Budget Planner & Tracker

Foxi

Budget Planner & Tracker

More money in your pocket by the end of the month.

Free to use and no account needed.

Get started now.

Get the app

Some graphics used on this post were made using icons from flaticon.

Latest Posts

Learn React, JavaScript and TypeScript

Learn React, JavaScript and TypeScript

Join the platform that top tier companies are using.
Master the skills you need to succeed as a software engineer and take your career to the next level with Pluralsight.

Start here

Become an expert in ReactJS, TypeScript, and JavaScript.

Here you will find my personal recomendations to you, for full disclosure I earn a small commission from some of these links, but I only recommend what I trust and personally use.

Good things are coming, don't miss out!

Good things are coming, don't miss out!

Follow me on Twitter to stay up to date and learn frontend, React, JavaScript, and TypeScript tips and tricks!

Are you a novice, intermediate or expert react engineer?

Find out here by taking my fun, interactive, quick quiz which takes approximately 1 - 3 minutes. How well will you will do?

Foxi - Budget Planner & Tracker

Foxi

Budget Planner & Tracker

More money in your pocket by the end of the month.

Free to use and no account needed.

Get started now.

Get the app