How to loop through object in JSX using React.js

25,792

Solution 1

Instead of $.each use map:

{AccountTypes.map(function(a) {
     return (
         <option key={a.id} val={a.id}>{a.name}</option>
     );
 })}

Solution 2

Points to note :

Your data is in an Object , not in an array : therefore to loop through it , you will have to use Object.keys(yourObject).map() instead of yourObject.map()

With this in mind ; here is the solution

var user = {
     fname:'John',
     lname : 'Doe',
     email:'[email protected]'
}

class App extends Component {
  render() {
    return (
      <p>
      <ul>
        {
          Object.keys(user).map((oneKey,i)=>{
            return (
                <li key={i}>{user[oneKey]}</li>
              )
          })
        }

      </ul>    
      </p>
    );
  }
}
Share:
25,792
kibowki
Author by

kibowki

Updated on June 22, 2021

Comments

  • kibowki
    kibowki almost 3 years

    So I have a React.js component, and I want to loop through an object I import to add HTML options to it. Here is what I tried, which is both ugly and does not work:

    import React from 'react';
    import AccountTypes from '../data/AccountType';
    
    const AccountTypeSelect = (props) => {  
      return (
        <select id={props.id} className = {props.classString} style={props.styleObject}>
            <option value="nothingSelected" defaultValue>--Select--</option>
            {
                $.each(AccountTypes, function(index) {
                    <option val={this.id}>this.name</option>
                })
            }
        </select>
      );
    };
    
    export default AccountTypeSelect;
    

    I received this error in the console from the above code:

    invariant.js?4599:38 - Uncaught Invariant Violation: Objects are not valid as a React child (found: object with keys {id, name, enabled, additionalInfo}). If you meant to render a collection of children, use an array instead or wrap the object using createFragment(object) from the React add-ons. Check the render method of AccountTypeSelect.

    Do I really need to convert each object into an array or wrap it with createFragment to use it? What is the best practice for this case?

  • Carlos
    Carlos over 7 years
    I would suggest to use some kind of prefix in the key value to avoid duplicate keys and the corresponding warnings and errors if you render more than one collection.
  • Felix Kling
    Felix Kling over 7 years
    The first example won't work since $.each doesn't return anything (or at least not the right thing).
  • Felix Kling
    Felix Kling over 7 years
    What the callback returns doesn't matter $.each is simply the wrong method to use here. See the docs: api.jquery.com/jquery.each .
  • Felix Kling
    Felix Kling over 7 years
    See my previous comment ;)
  • kibowki
    kibowki over 7 years
    What is with the key attribute - why do I need to use that? Seems strange I need to add a seemingly arbitrary attribute when all I want to do is place in a simple option tag.
  • Kevin
    Kevin over 7 years
    The key attribute is described here under "Reconciliation": facebook.github.io/react/docs/multiple-components.html. But basically is to ensure that react properly updates the DOM when your child elements are dynamically generated (a weak explanation, I know, but I don't want to repeat the react docs in a comment). My use of a loop variable was poor form in that regard, so I've updated the answer. Sorry!