Loops & iterations

web
mobile

Author: Dawid Adach

-

Disclaimer: In this lesson, we will quickly go through loops in React. I assume that you already know how to code loops in JS - if you don't then check this tutorial first.


1. For loop


Currently, we have our main App Component 

            class App extends Component {
                state = {};
                render() {
                  return (
                    <React.Fragment>
                      <MDBContainer>
                        <MDBRow>
                          <MDBCol md="9">
                            <Event title="Meeting with John" time="10:00" />
                          </MDBCol>
                          <MDBCol md="3" />
                        </MDBRow>
                      </MDBContainer>
                    </React.Fragment>
                  );
                }
              }              
     
and the child component:

            class Event extends Component {
                render() {
                  return (
                    <React.Fragment>
                      <h3>
                        {this.props.time} - {this.props.title}
                      </h3>
                    </React.Fragment>
                  );
                }
              }              
     
A typical JS for loop looks like this one below:

            for (i = 0; i < 5; i++) {
                text += "The number is " + i + " ";
              }
                           
     
Let's try to use it within our App component:

            <MDBCol md="9">
                for (i = 0; i < 5; i++) {
                    text += "The number is " + i + " ";
                }
            </MDBCol>
                    
    
As soon as we save the file, the compiler will raise an Unexpected token error:

Compiler error

Apparently, React does not like for loops in its render() method! How do we solve this?

What we need to do is to use a loop in a separate function outside render(), but still inside the class. Then we can call the creating function inside render to get the result.

            myFunction() {
                var text = " ";
                var i;
                for (i = 0; i < 5; i++) {
                  text += " The number is " + i;
                }
                return text;
              }            
      
and call it within the render() method:

            <MDBCol md="9"> {this.myFunction()} </MDBCol>
      

Preview:

For Loop

2. Looping through components


Let's create an array containing some events in our App component:

            class App extends Component {
                constructor(props) {
                  super(props);
                  this.state = {
                    events: [
                      { time: "10:00", title: "Breakfast with Simon" },
                      { time: "10:30", title: "Daily Standup Meeting (recurring)" },
                      { time: "11:00", title: "Call with HRs" }
                    ]
                  };
                }              
      
Since we cannot use a for loop directly in our render() method, let's modify our myLoopFunction() to work with our components:

            myLoopFunction() {
                var myArray = [];
                var i;
                for (i = 0; i < this.state.events.length; i++) {
                  myArray[i] = (
                    <Event
                      time={this.state.events[i].time}
                      title={this.state.events[i].title}
                    />
                  );
                }
                return myArray;
              }            
     

As you might notice we made a few changes: 
  • we used an array instead of a string variable to collect loop output
  • instead of hard-coded values, we are looping until we reach the length of our events array (events.length)
  • we refer to corresponding events in a table using an iterator (i) (this.state.events[i])

Preview:

Loop preview
It works, however, there is a much better and easy way to loop within the render() method without using extra function. 

3. Using map()


Instead of typical loop we can use map() function: 

            {this.state.events.map(event => (
                <Event time={event.time} title={event.title} />
              ))}              
     
The result is the same and it's much shorter. Furthermore we can use it directly inside the render() method. 

We can now delete our myLoopFunction() since we don't need it anymore. 

4. "key" attribute


The map() function makes it easier to iterate through arrays, however, there is one important thing to remember while using map() in React. When you open a console, you will see that React complains about missing key attribute:

Missing key error

It is important for React to maintain the key for each element generated by the map() function. This way React can handle the minimal DOM change. Let's add a few more items to our events array: 

            events: [
            {
              id: 1,
              time: "10:00",
              title: "Breakfast with Simon",
              location: "Lounge Caffe",
              description: "Discuss Q3 targets"
            },
            {
              id: 2,
              time: "10:30",
              title: "Daily Standup Meeting (recurring)",
              location: "Warsaw Spire Office"
            },
            { id: 3, time: "11:00", title: "Call with HRs" },
            {
              id: 4,
              time: "11:00",
              title: "Lunch with Timothy",
              location: "Canteen",
              description:
                "Project evaluation ile declaring a variable and using an if statement is a fine way to conditionally render a component, sometimes you might want to use a"
            }
          ]
          
     

Now each element has its own id, which we will use as a key. We also extended some of our events with a location as well as a description.  

Let's update our map correspondingly: 


            {this.state.events.map(event => (
                <Event
                  key={event.id}
                  id={event.id}
                  time={event.time}
                  title={event.title}
                  location={event.location}
                  description={event.description}
                />
              ))}          
      
The last step is to update our Event component to render our new metadata:

<h3>
  {this.props.time} - {this.props.title}
</h3>
<h6>Location: {this.props.location}</h6>
<p>Desc: {this.props.description}</p>

     

Preview:


Output of the map() function

Some of the values are empty and looks odd, that's why we will learn more about conditional rendering in the next lesson.


Rate this lesson

Previous lesson Download Next lesson

Spread the word:
Do you need help? Use our support forum

About the author

Dawid Adach
For more than 5 years Dawid worked as an IT Consultant specializing in SOA/EAI/ESB in the banking domain. He gained experience working in countries like Netherlands, Belgium, Poland and India developing enterprise-class systems for the most prestigious companies. Since co-founding mdbootstrap.com & brandflow.net in 2016 he has been using and teaching technologies such as Angular, TypeScript, PHP, AJAX, Mongo, SQL, Hadoop Stack, Virtualization, Automation and many others...