Click to share! ⬇️

Rendering A-List With React

Creating a list in the browser is a super common technique for displaying a list of data. In this tutorial, we’ll learn about how to create a list of items using React. It’s a little different from how you might approach this when using some of the other popular UI frameworks like Vue or Angular. In those other frameworks, you have customized directives such as v-for or ng-for to iterate directly in HTML. With react, the approach is to use native JavaScript for iteration. So in React, you can use the map() function to iterate over an array and create a list. Let’s see how to do that now.


Creating A Static List

Ok first things first. Before we even use any JavaScript arrays to help with creating a list, let’s remind ourselves how to simply render a static list. So with this markup, we should be in business.

import React, { Component } from "react";

class Item extends Component {
  state = {};

  render() {
    return (
      <React.Fragment>
        <ul class="list-group">
          <li class="list-group-item list-group-item-primary">List item 1</li>
          <li class="list-group-item list-group-item-primary">List item 2</li>
          <li class="list-group-item list-group-item-primary">List item 3</li>
        </ul>
      </React.Fragment>
    );
  }
}

export default Item;

react static list


Rendering A List Dynamically

To render a list dynamically in React, we start by adding a property to the state object. We can populate that property with an array of strings like so.

import React, { Component } from "react";

class Item extends Component {
  state = {
    listitems: ['List Item 1','List Item 2', 'List Item 3']
  };

  render() {
    return (
      <React.Fragment>

      </React.Fragment>
    );
  }
}

export default Item;

Great. Now we want to move to the render() method to render each list item dynamically. This is where in other frameworks you would reach for ng-for or v-for type directives. We can’t do that in React. Instead we reach for the built-in map function in JavaScript. We can use the map function to map each item in the array to a react element. Notice that we pass an arrow function as an argument to the map function.

import React, { Component } from "react";

class Item extends Component {
  state = {
    listitems: ["List Item 1", "List Item 2", "List Item 3"]
  };

  render() {
    return (
      <React.Fragment>
        <ul className="list-group">
          {this.state.listitems.map(listitem => (
            <li className="list-group-item list-group-item-primary" />
          ))}
        </ul>
      </React.Fragment>
    );
  }
}

export default Item;

At this point we do have a list, but each li is empty.
react map function list

How can we fix that? All we need to do is use the curly braces in the JSX expression to output each list item like so.

import React, { Component } from "react";

class Item extends Component {
  state = {
    listitems: ["List Item 1", "List Item 2", "List Item 3"]
  };

  render() {
    return (
      <React.Fragment>
        <ul className="list-group">
          {this.state.listitems.map(listitem => (
            <li className="list-group-item list-group-item-primary">
              {listitem}
            </li>
          ))}
        </ul>
      </React.Fragment>
    );
  }
}

export default Item;

There we go! We have our dynamically rendered list using React along with the JavaScript map function.

Just to prove that the list is dynamic, we can change the data in the listitems array and see what happens.

  state = {
    listitems: ["Spring", "Summer", "Fall"]
  };

react dynamic list via map


Each child in a list should have a unique “key” prop

We now have a list rendering out nicely but we are not done. By inspecting the console in the browser, we now notice a warning message in red text.

index.js:1446 Warning: Each child in a list should have a unique “key” prop.

Check the render method of `Item`. See https://fb.me/react-warning-keys for more information.

What is happening here? The reason React is complaining about this is because it needs to uniquely identify each item in our list. If the state of this react element in the virtual dom changes, React needs to quickly figure out which element changed and where in the real dom it needs to reflect that change. Ok so how do we fix this? Well, anytime we use the map function to render a list of items, we need to set the key attribute on the li of the list. Here is how to do that.

import React, { Component } from "react";

class Item extends Component {
  state = {
    listitems: ["Spring", "Summer", "Fall"]
  };

  render() {
    return (
      <React.Fragment>
        <ul className="list-group">
          {this.state.listitems.map(listitem => (
            <li
              key={listitem}
              className="list-group-item list-group-item-primary"
            >
              {listitem}
            </li>
          ))}
        </ul>
      </React.Fragment>
    );
  }
}

export default Item;

So in the highlighted line above, notice we have now added key set to a dynamic value on the li item. Now in this case, each listitem is a string, and each string is unique. Therefore, we can use listitem as the value for key. Once again we inspect the developer tools console and we no longer get the error of Each child in a list should have a unique “key” prop. In other scenarios the array your dealing with might contain objects. In that case each object could have a unique id, and that would be the value for the key attribute. Also, this unique key is unique per list rendered, not for the whole application.


Rendering an Array of Objects as a List

To finish up, let’s render out a list where the state property contains an array of objects. That way we can see how the unique key approach works when you are using objects instead of simple strings.

import React, { Component } from "react";

class Item extends Component {
  state = {
    listitems: [
      {
        id: 0,
        context: "Primary",
        modifier: "list-group-item list-group-item-primary"
      },
      {
        id: 1,
        context: "Secondary",
        modifier: "list-group-item list-group-item-secondary"
      },
      {
        id: 2,
        context: "Success",
        modifier: "list-group-item list-group-item-success"
      },
      {
        id: 3,
        context: "Danger",
        modifier: "list-group-item list-group-item-danger"
      },
      {
        id: 4,
        context: "Warning",
        modifier: "list-group-item list-group-item-warning"
      }
    ]
  };

  render() {
    return (
      <React.Fragment>
        <ul className="list-group">
          {this.state.listitems.map(listitem => (
            <li key={listitem.id} className={listitem.modifier}>
              {listitem.context}
            </li>
          ))}
        </ul>
      </React.Fragment>
    );
  }
}

export default Item;

]
react render array of objects as list


Read More about List Rendering In React


Rendering A List With React Summary

As we have seen rendering a list in React is not so bad. While React does not have the syntactic sugar of ng-for or v-for, we can simply use the JavaScript map function to produce the same effect. That seems to be a common theme in React: Using native JavaScript to accomplish certain tasks while letting React manage the virtual dom.

Click to share! ⬇️