#8 Rendering Lists of Elements - Delightful React

Subscribe to my newsletter and never miss my upcoming articles

Now, in our homepage, we want to render a list of blog posts. Typically, in such scenarios in a fully production ready app,

  • the data would be fetched from a server in the form of an array of objects.
  • And each of these objects would be rendered as a React component.

We know how to render strings, numbers, booleans and even values in an object. But how do we render a list of items in React?

Asset_13.png

*Note: This article is a part of the Delightful React Series, as part of which, I am releasing one chapter every day for 25 days. Please support me in anyway you can! *


Imagine a list of ListItem components and each ListItem showing some details of a blog post like title, image, a short description, etc. And when clicked the app will go to the blog detail page and show the entire blogpost.

So in this chapter, we will learn to render a list of objects as react components.

Before that though, let's start small by rendering a list of strings.

Rendering lists of strings

So, let's create an array called blog post titles and we'll just put in some random text in there. And inside our home component, let's do this.

import Heading from "../src/components/Heading";
const BLOGPOST_TITLES = [
  "Platea dictumst etiam faucibus cursus urna ut",
  "Ultrices posuere cubilia curae duis",
  "Vulputate elementum nullam varius nulla facilisi cras"
]

function Home(props) {
  return (
    <div>
      <Heading>All Posts</Heading>
      <div className="post-list">
        {BLOGPOST_TITLES}
      </div>
    </div>
  );
}

export default Home;

This works well. Nothing much to see here. We have already seen that React is capable of rendering an array of strings without much work.

Rendering strings as React elements

Now, the next step is to render this array of strings as React elements.

  • So instead of rendering the strings directly, we will render a list of paragraphs.
  • Let's create an array of paragraph elements, and for each string inside our BLOGPOST_TITLES, we will create a paragraph element and push that into this new array and render the array instead.
import Heading from "../src/components/Heading";
const BLOGPOST_TITLES = [
  "Platea dictumst etiam faucibus cursus urna ut",
  "Ultrices posuere cubilia curae duis",
  "Vulputate elementum nullam varius nulla facilisi cras"
]

const TITLE_PARAGRAPHS = []
for(const title of BLOGPOST_TITLES){
  TITLE_PARAGRAPHS.push(<p>{title}</p>)
}

function Home(props) {
  return (
    <div>
      <Heading>All Posts</Heading>
      <div className="post-list">
        {TITLE_PARAGRAPHS}
      </div>
    </div>
  );
}

export default Home;

Preview looks good

Group_3s.png

Everything looks good except that there is a warning in the console. It's a warning, but it's an important warning which we will fix soon.

Group_3asdf.png

The array.map method

So we used a for loop to create an Array out of another Array. There is a more easier way of doing the same thing and that is by using the .map method. Every array in JavaScript has a method called map. The map method, creates a new Array, out of the existing Array. It creates a new array by using a transformation function.

So, now we can do this.


const BLOGPOST_TITLES = [
  "Platea dictumst etiam faucibus cursus urna ut",
  "Ultrices posuere cubilia curae duis",
  "Vulputate elementum nullam varius nulla facilisi cras"
]

const TITLE_PARAGRAPHS = BLOGPOST_TITLES.map(title => <p>{title}</p>);

The transformation function is run with each element in the existing array and the return value of the transformation function is used to create each element in the second array. So, for each title, in the original array, we created a paragraph element containing the title in the new array. We will be using the map method a lot of the time with React and it’s a concise way of creating arrays of elements and components from data.

Let us take a look at a warning.

Group_3asdf.png

The warning is saying that we need to give a unique key for each rendered array of React elements. We know that the title is unique for all of strings, so that will be perfect for the key prop. Let's put the key prop to be title as well and now warning will now disappear.

const TITLE_PARAGRAPHS = BLOGPOST_TITLES.map(title => <p key={title}>{title}</p>);

That is good. But..

Now, why should the key prop be unique?

Asset_14.png

And what purpose does the key prop solve? This has to do with React's reconciliation process and we will address this in detail about 4 chapters from now.

I will explain it briefly here.

It's fine if this is a bit confusing, but I will show a proper demo after I talk about state in a few chapters. Anyway, here is the explanation.

  • React element/component instances can be optionally given a key prop as an identifier. This key prop is simply like an id for that instance.
  • When React renders elements in lists, it needs to keep track of which React element corresponds to which DOM element. It also has to handle diffing across rerenders to ensure it is very performant and fast.
  • In a list of React elements, when some elements are added and removed at some positions in the list, React doesn't necessarily remove the DOM nodes in the exact same positions. It makes changes depending on whichever way causes least updates to the DOM.
  • The key prop as it is unique for each item in the list, helps React keep the mapping between React and DOM elements intact when making such updates.

In about 3-4 chapters from now, I will show a demo that breaks a list when used with a faulty key prop and then I will also you how to fix it Stay tuned!

Rendering a list of objects

Now, we are ready to take this further. Let’s render an array of objects using the same logic. I created an array of dummy objects for this scenario and you can grab it from over here. assets.delightful-react.com/blogposts.js

  • Copy the contents of the file at here and paste them in src/data/blogposts.js like so.
const BLOGPOSTS = [
    {
      id: 1,
      title: "Platea dictumst etiam faucibus cursus urna ut",
      content: "Fusce consequat. Nulla nisl. Nunc nisl.",
      img:  "https://i.picsum.photos/id/881/8..",
      tags: ["React", "Javascript", "Delightful"],
      featured: true,
    },
    ...
  ];

  export default BLOGPOSTS;
  • Let’s import this into our home page like so.
import BLOGPOSTS from '../src/data/blogposts';
  • Let’s render the BLOGPOSTS array using the map function like so. We know that the map function gives us each blogPostObject within the transformation function. Let’s grab the title and img values from it and display.
import Heading from "../src/components/Heading";
import BLOGPOSTS from "../src/data/blogposts";

function Home(props) {
  return (
    <div>
      <Heading>All Posts</Heading>
      <div className="post-list">
        {BLOGPOSTS.map((blogPostObject) => {
          return (
            <div key={blogPostObject.title} className="post-list-item">
              <img src={blogPostObject.img} />
              <div>
                <h1>{blogPostObject.title}</h1>
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
}

Exciting stuff ahead

Group_3.png

Excellent work! We now have a home page that can show a list of blogposts. Let’s keep moving forward!

In the next chapter, I am going to start talking about the most fascinating aspect of React which is Hooks!

Thanks and Please support my work

Writing blog posts and making videos is an effort that takes many hours in my day. I do it because I love teaching and make great content. However, I need your support too. Please support my work and follow my social accounts to help me continue to make great content. Here are my social links.

Follow me on Twiter

Subscribe to my channel on Youtube

Thank you!

No Comments Yet