How to render an array of objects in React?

JavascriptReactjsReact Router

Javascript Problem Overview


could you please tell me how to render a list in react js. I do like this

https://plnkr.co/edit/X9Ov5roJtTSk9YhqYUdp?p=preview

class First extends React.Component {
  constructor (props){
    super(props);

  }

  render() {
     const data =[{"name":"test1"},{"name":"test2"}];
    const listItems = data.map((d) => <li key={d.name}>{d.name}</li>;
    
    return (
      <div>
      hello
      </div>
    );
  }
} 

Javascript Solutions


Solution 1 - Javascript

You can do it in two ways:

First:

render() {
    const data =[{"name":"test1"},{"name":"test2"}];
    const listItems = data.map((d) => <li key={d.name}>{d.name}</li>);

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

Second: Directly write the map function in the return

render() {
    const data =[{"name":"test1"},{"name":"test2"}];
    return (
      <div>
      {data.map(function(d, idx){
         return (<li key={idx}>{d.name}</li>)
       })}
      </div>
    );
  }

Solution 2 - Javascript

https://facebook.github.io/react/docs/jsx-in-depth.html#javascript-expressions

>You can pass any JavaScript expression as children, by enclosing it within {}. For example, these expressions are equivalent:

> foo

> {'foo'}

>This is often useful for rendering a list of JSX expressions of arbitrary length. For example, this renders an HTML list:

> function Item(props) { > return

  • {props.message}
  • ; > }

    > function TodoList() { const todos = ['finish doc', 'submit pr', 'nag dan to review']; return (

      {todos.map((message) => )}
    ); }


    class First extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          data: [{name: 'bob'}, {name: 'chris'}],
        };
      }
      
      render() {
        return (
          <ul>
            {this.state.data.map(d => <li key={d.name}>{d.name}</li>)}
          </ul>
        );
      }
    }
    
    ReactDOM.render(
      <First />,
      document.getElementById('root')
    );
      
    

    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
    <div id="root"></div>
    

    Solution 3 - Javascript

    Shubham's answer explains very well. This answer is addition to it as per to avoid some pitfalls and refactoring to a more readable syntax

    Pitfall : There is common misconception in rendering array of objects especially if there is an update or delete action performed on data. Use case would be like deleting an item from table row. Sometimes when row which is expected to be deleted, does not get deleted and instead other row gets deleted.

    To avoid this, use key prop in root element which is looped over in JSX tree of .map(). Also adding React's Fragment will avoid adding another element in between of ul and li when rendered via calling method.

    state = {
        userData: [
            { id: '1', name: 'Joe', user_type: 'Developer' },
            { id: '2', name: 'Hill', user_type: 'Designer' }
        ]
    };
    
    deleteUser = id => {
        // delete operation to remove item
    };
    
    renderItems = () => {
        const data = this.state.userData;
    
        const mapRows = data.map((item, index) => (
            <Fragment key={item.id}>
                <li>
                    {/* Passing unique value to 'key' prop, eases process for virtual DOM to remove specific element and update HTML tree  */}
                    <span>Name : {item.name}</span>
                    <span>User Type: {item.user_type}</span>
                    <button onClick={() => this.deleteUser(item.id)}>
                        Delete User
                    </button>
                </li>
            </Fragment>
        ));
        return mapRows;
    };
    
    render() {
        return <ul>{this.renderItems()}</ul>;
    }
    

    Important : Decision to use which value should we pass to key prop also matters as common way is to use index parameter provided by .map().

    TLDR; But there's a drawback to it and avoid it as much as possible and use any unique id from data which is being iterated such as item.id. There's a good article on this - https://medium.com/@robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318

    Solution 4 - Javascript

    import React from 'react';
    
    class RentalHome extends React.Component{
        constructor(){
            super();
            this.state = {
                rentals:[{
                    _id: 1,
                    title: "Nice Shahghouse Biryani",
                    city: "Hyderabad",
                    category: "condo",
                    image: "http://via.placeholder.com/350x250",
                    numOfRooms: 4,
                    shared: true,
                    description: "Very nice apartment in center of the city.",
                    dailyPrice: 43
                  },
                  {
                    _id: 2,
                    title: "Modern apartment in center",
                    city: "Bangalore",
                    category: "apartment",
                    image: "http://via.placeholder.com/350x250",
                    numOfRooms: 1,
                    shared: false,
                    description: "Very nice apartment in center of the city.",
                    dailyPrice: 11
                  },
                  {
                    _id: 3,
                    title: "Old house in nature",
                    city: "Patna",
                    category: "house",
                    image: "http://via.placeholder.com/350x250",
                    numOfRooms: 5,
                    shared: true,
                    description: "Very nice apartment in center of the city.",
                    dailyPrice: 23
                  }]
            }
        }
        render(){
            const {rentals} = this.state;
            return(
                <div className="card-list">
                    <div className="container">
                        <h1 className="page-title">Your Home All Around the World</h1>
                        <div className="row">
                            {
                                rentals.map((rental)=>{
                                    return(
                                        <div key={rental._id} className="col-md-3">
                                            <div className="card bwm-card">
                                            <img 
                                            className="card-img-top" 
                                            src={rental.image}
                                            alt={rental.title} />
                                            <div className="card-body">
                                            <h6 className="card-subtitle mb-0 text-muted">
                                                {rental.shared} {rental.category} {rental.city}
                                            </h6>
                                            <h5 className="card-title big-font">
                                                {rental.title}
                                            </h5>
                                            <p className="card-text">
                                                ${rental.dailyPrice} per Night &#183; Free Cancelation
                                            </p>
                                            </div>
                                            </div>
                                        </div>
                                    )
                                })
                            }
                            
                        </div>
                    </div>
                </div>
            )
        }
    }
    
    export default RentalHome;
    

    Solution 5 - Javascript

    Try this:

    class First extends React.Component {
      constructor (props){
        super(props);
    
      }
    
      render() {
         const data =[{"name":"test1"},{"name":"test2"}];
        const listItems = data.map((d) => <li key={d.name}>{d.name}</li>;
        
        return (
          <div>
          {listItems}
          </div>
        );
      }
    } 
    

    Solution 6 - Javascript

    Try this below code in app.js file, easy to understand

    function List({}) {
      var nameList = [
        { id: "01", firstname: "Rahul", lastname: "Gulati" },
        { id: "02", firstname: "Ronak", lastname: "Gupta" },
        { id: "03", firstname: "Vaishali", lastname: "Kohli" },
        { id: "04", firstname: "Peter", lastname: "Sharma" }
      ];
      const itemList = nameList.map((item) => (
        <li>
          {item.firstname} {item.lastname}
        </li>
      ));
      return (
        <div>
          <ol style={{ listStyleType: "none" }}>{itemList}</ol>
        </div>
      );
    }
    
    export default function App() {
      return (
        <div className="App">
          <List />
        </div>
      );
    }
    

    Attributions

    All content for this solution is sourced from the original question on Stackoverflow.

    The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

    Content TypeOriginal AuthorOriginal Content on Stackoverflow
    Questionuser944513View Question on Stackoverflow
    Solution 1 - JavascriptShubham KhatriView Answer on Stackoverflow
    Solution 2 - JavascriptdtingView Answer on Stackoverflow
    Solution 3 - JavascriptMeet ZaveriView Answer on Stackoverflow
    Solution 4 - JavascriptSandeep MukherjeeView Answer on Stackoverflow
    Solution 5 - Javascriptuser5889334View Answer on Stackoverflow
    Solution 6 - JavascriptMeet LukkaView Answer on Stackoverflow