javascripting
javascripting

Reputation: 1153

React - how to render multiple buttons with a regular for loop?

Sorry if its very basic but: when rendering multiple buttons (0-9) in an iteration - What is the difference btw map and for loop ? Why does the for loop only renders the first element (0) while map works fine? Why do I have to first push the buttons into an array and return that then (as seen on other examples) ? Can I use regular for loop and render buttons without pushing it into an arary? Thanks!

 import React from 'react';

    const Keys = () => {        
       const renderKeys = () => {
         //works fine
          var arr = [1,2,3,4,5,6,7,8,9]
          return arr.map((val) => {
              return <button>{val}</button>
            })                 
        };

        const renderKeys = () => {       
              //does not work    
              for (var i=0; i<10; i++) {
               return <button>{i}</button>
            }
        };

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

Upvotes: 2

Views: 16608

Answers (2)

Cat_Enthusiast
Cat_Enthusiast

Reputation: 15708

When you call return inside a for-loop it stops executing the loop. That's why you only get back the first button.

However, calling return inside a .map() will not stop the loop from iterating. Instead you use return to explicitly define what you want to have in a new array.

Note that .map() creates a brand new array by using elements from an existing array. You are free to utilize those elements any way you want which makes it suitable for rendering JSX.

Example:

const numbers = [1, 2, 3, 4, 5]
const numbersMultipledByTwo = numbers.map((number) => {
   return <div>{ number * 2 }</div>
})

Theoretically, you could accomplish the same effect using a for-loop but that will also require help from a second array.

Working code:

import React from "react";
import ReactDOM from "react-dom";

import "./styles.css";

class App extends React.Component{
  getButtonsUsingMap = () => {
    const array = [1, 2, 3 ,4, 5]

    return array.map((number) => {
      return <button>{number}</button>
    })

  }

  getButtonsUsingForLoop = (num) => {
    const array = []

    for(var i = 1; i <= num; i++){
      array.push(<button>{i}</button>)
    }

    return array
  }

  render(){
    return(
      <div>
        <h4>Using .map()</h4>
        {this.getButtonsUsingMap()}
        <h4>using for-loop</h4>
        {this.getButtonsUsingForLoop(5)}
      </div>
    )
  }
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

In that getButtonsUsingForLoop function, you can see there are more explicit demands to make it work. First we need to satisfy the argument. Then initialize a new array. Then define a boundary for the loop. Iterate and push JSX to the empty-array. Then finally return that array. So the logic is not very succinct.

Whereas on the other-hand, a .map() essentially handles all of that. As long as you have a pre-existing array to iterate over (which 99% of the time you will be dealing with some sort of state or props-array.)

See sandbox: https://codesandbox.io/s/pensive-leftpad-lt5ml

Upvotes: 13

exside
exside

Reputation: 3894

What is the difference btw map and for loop?

.map() iterates an array (and arrays only) while a for loop could be lazily summarized as a more "general" loop mechanism that is independent of any specific data type.

Why does the for loop only renders the first element (0) while map works fine?

Because you're returning from the function in the first iteration of the for loop with

const renderKeys = () => {       
  //does not work    
  for (var i=0; i<10; i++) {
    return <button>{i}</button> // this returns from the function you're in
  }
};

.map() works fine because it returns a new array from iterating the input-array, e.g.:

const renderKeys = () => {
  // works fine
  var arr = [1,2,3,4,5,6,7,8,9]
  return arr.map((val) => { // here you return the new array created by map
    return <button>{val}</button>
  });
};

Why do I have to first push the buttons into an array and return that then (as seen on other examples)?

basically to "imitate" what map does, e.g. creating a new array from the iteration.

Can I use regular for loop and render buttons without pushing it into an array?

Directly return you mean? I don't think it's possible, but maybe somebody else does know a way!

Why I think it's not possible?

return (
  <div>
    {renderKeys()}
  </div>
)

in JSX you return a function and you can't pass a for loop as a function argument directly, e.g. this:

return (
  <div>
  for (var i=0; i<10; i++) {
    <button>{i}</button>
  }
  </div>
)

would most likely give you a syntax error...

Upvotes: 5

Related Questions