If you are using React JS and want to add a component multiple times, maybe inserting it into some JSX code, you could think of using a for loop inside the return statement of your JSX.
But this approach doesn’t work in JSX, as you should compose the returned value from the render function of values, while a for loop is an imperative way of doing thing and doesn’t return anything.
Suppose you want to print four times the Hello World string.
We build a basic component Hello World, the following one
1 2 3 4 5 |
class HelloWorld extends React.Component { render() { return <p>Hello World</p>; } } |
Then, we try to add it multiple times to some JSX code.
The wrong approach
What you probably have done so far is trying something like
1 2 3 4 5 6 7 8 9 |
class HelloWorldMultiple extends React.Component { render() { return <h1> for (let i=0; i < 4; i++) { <HelloWorld key={i} /> } </h1>; } } |
This doesn’t work, so let’s see the correct approach
How to correctly loop inside JSX
1 2 3 4 5 6 7 8 9 |
class HelloWorldMultiple extends React.Component { render() { let rows = []; for (let i=0; i < 4; i++) { rows.push(<HelloWorld key={i} />) } return <h1>{rows}</h1>; } } |
Here we see how a component named HelloWorldMultiple can add another component Hello World multiple times:
- create an array of rows containing the basic component
- add the just created array to your “template” using curly braces
How to add a component multiple times with an IIFE
You can also use an IIFE (Immediately-invoked function expression), which returns a result and so its ok
1 2 3 4 5 6 7 8 9 10 11 12 13 |
class HelloWorldMultiple extends React.Component { render() { return <h1> { function() { let rows = []; for (let i=0; i < 4; i++) { rows.push(<HelloWorld key={i} />); } return rows; }() } </h1> } } |
How to loop inside JSX with map
If you already have an array of objects and want to add them into your template, you can use map this way
1 2 3 4 5 6 7 8 9 10 11 |
class HelloWorldMultiple extends React.Component { render() { let rows = []; for (let i=0; i < 4; i++) { rows.push(your_object_here); } return <h1> { rows.map((object, i) => <ObjectRow obj={object} key={i}/>) } </h1> } } |
The complete example
What follows is the complete example of our code to print Hello World four times inside an h1 HTML tag. This is only to show how the code should be and uses Babel standalone, real code should be precompiled using Babel with a module bundler like Browserify or Webpack
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
<!DOCTYPE html> <html lang="en-us"> <head> <meta charset="UTF-8"> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.2.0/umd/react.development.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.2.0/umd/react-dom.development.js"></script> <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script> </head> <body> <div id="output"></div> <script type="text/babel"> class HelloWorld extends React.Component { render() { return <p>Hello World</p>; } } class HelloWorldMultiple extends React.Component { render() { let rows = []; for (let i=0; i < 4; i++) { rows.push(<HelloWorld key={i} />) } return <h1>{rows}</h1>; } } ReactDOM.render( <HelloWorldMultiple />, document.getElementById('output') ); </script> </body> </html> |
Babel repl
To better understand why you need to use the for outside the return statement, you can use Babel REPL, which translates JSX code into vanilla Javascript on the fly.