Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to loop and render elements in React.js without an array of objects to map?

People also ask

How do you loop components in React?

Using the Array map function is a very common way to loop through an Array of elements and create components according to them in React. This is a great way to do a loop which is a pretty efficient and is a tidy way to do your loops in JSX. It's not the only way to do it, but the preferred way.

How do you loop a map in React JS?

In React, the map() function is most commonly used for rendering a list of data to the DOM. To use the map() function, attach it to an array you want to iterate over. The map() function expects a callback as the argument and executes it once for each element in the array.


Updated: As of React > 0.16

Render method does not necessarily have to return a single element. An array can also be returned.

var indents = [];
for (var i = 0; i < this.props.level; i++) {
  indents.push(<span className='indent' key={i}></span>);
}
return indents;

OR

return this.props.level.map((item, index) => (
    <span className="indent" key={index}>
        {index}
    </span>
));

Docs here explaining about JSX children


OLD:

You can use one loop instead

var indents = [];
for (var i = 0; i < this.props.level; i++) {
  indents.push(<span className='indent' key={i}></span>);
}
return (
   <div>
    {indents}
    "Some text value"
   </div>
);

You can also use .map and fancy es6

return (
   <div>
    {this.props.level.map((item, index) => (
       <span className='indent' key={index} />
    ))}
    "Some text value"
   </div>
);

Also, you have to wrap the return value in a container. I used div in the above example

As the docs say here

Currently, in a component's render, you can only return one node; if you have, say, a list of divs to return, you must wrap your components within a div, span or any other component.


Here is more functional example with some ES6 features:

'use strict';

const React = require('react');

function renderArticles(articles) {
    if (articles.length > 0) {      
        return articles.map((article, index) => (
            <Article key={index} article={article} />
        ));
    }
    else return [];
}

const Article = ({article}) => {
    return ( 
        <article key={article.id}>
            <a href={article.link}>{article.title}</a>
            <p>{article.description}</p>
        </article>
    );
};

const Articles = React.createClass({
    render() {
        const articles = renderArticles(this.props.articles);

        return (
            <section>
                { articles }
            </section>
        );
    }
});

module.exports = Articles;

Array.from() takes an iterable object to convert to an array and an optional map function. You could create an object with a .length property as follows:

return Array.from({length: this.props.level}, (item, index) => 
  <span className="indent" key={index}></span>
);

I'm using Object.keys(chars).map(...) to loop in render

// chars = {a:true, b:false, ..., z:false}

render() {
    return (
       <div>
        {chars && Object.keys(chars).map(function(char, idx) {
            return <span key={idx}>{char}</span>;
        }.bind(this))}
        "Some text value"
       </div>
    );
}

You can still use map if you can afford to create a makeshift array:

{
    new Array(this.props.level).fill(0).map((_, index) => (
        <span className='indent' key={index}></span>
    ))
}

This works because new Array(n).fill(x) creates an array of size n filled with x, which can then aid map.

array-fill