Reputation: 1153
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
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.
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
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