styler
styler

Reputation: 16511

How to loop an object in React?

New to React and trying to loop Object attributes but React complains about Objects not being valid React children, can someone please give me some advice on how to resolve this problem? I've added createFragment but not completely sure where this needs to go or what approach I should take?

JS

var tifs = {1: 'Joe', 2: 'Jane'};
var tifOptions = Object.keys(tifs).forEach(function(key) {
    return <option value={key}>{tifs[key]}</option>
});

Render function

render() {
        const model = this.props.model;

        let tifOptions = {};

        if(model.get('tifs')) {
            tifOptions = Object.keys(this.props.model.get('tifs')).forEach(function(key) {
                return <option value={key}>{this.props.model.get('tifs')[key]}</option>
            });
        }

        return (
            <div class={cellClasses}>

                    <div class="grid__col-5 text--center grid__col--bleed">
                        <h5 class="flush text--uppercase">TIF</h5>
                        <select id="tif" name="tif" onChange={this.handleChange}>
                            {tifOptions}
                        </select>
                    </div>

            </div>
        );
    }

Error in console

If you meant to render a collection of children, use an array instead or wrap the object using createFragment(object)

Upvotes: 126

Views: 327270

Answers (8)

Bagde Avinash
Bagde Avinash

Reputation: 71

{
   Object.entries(tifOptions).map(([key, value], index) =>
       console.log("Key" + Key + "::>" + "Value" + value);
)}

Upvotes: 7

Felix H.
Felix H.

Reputation: 1112

When I use Object.entries with map, I use Array Destructuring like the following and just call them directly.

Object.entries(tifs).map(([key, value]) => (
    <div key={key}>{value}</div>
));

Upvotes: 18

Josep Vicent Ibanez
Josep Vicent Ibanez

Reputation: 1758

You can use it in a more compact way as:

const tifs = {1: 'Joe', 2: 'Jane'};
...

return (
   <select id="tif" name="tif" onChange={this.handleChange}>  
      { Object.entries(tifs).map((t,k) => <option key={k} value={t[0]}>{t[1]}</option>) }          
   </select>
)

And another slightly different flavour:

 Object.entries(tifs).map(([key,value],i) => <option key={i} value={key}>{value}</option>)  

Upvotes: 40

Baqer Naqvi
Baqer Naqvi

Reputation: 6514

You can use map function

{Object.keys(tifs).map(key => (
    <option value={key}>{tifs[key]}</option>
))}

Upvotes: 5

Oleg Zinchenko
Oleg Zinchenko

Reputation: 631

const tifOptions = [];

for (const [key, value] of Object.entries(tifs)) {
    tifOptions.push(<option value={key} key={key}>{value}</option>);
}

return (
   <select id="tif" name="tif" onChange={this.handleChange}>  
      { tifOptions }          
   </select>
)

Upvotes: 7

Ben Rawner
Ben Rawner

Reputation: 401

you could also just have a return div like the one below and use the built in template literals of Javascript :

const tifs = {1: 'Joe', 2: 'Jane'};

return(

        <div>
            {Object.keys(tifOptions).map((key)=>(
                <p>{paragraphs[`${key}`]}</p>
            ))}
        </div>
    )

Upvotes: 5

tobiasandersen
tobiasandersen

Reputation: 8688

The problem is the way you're using forEach(), as it will always return undefined. You're probably looking for the map() method, which returns a new array:

var tifOptions = Object.keys(tifs).map(function(key) {
    return <option value={key}>{tifs[key]}</option>
});

If you still want to use forEach(), you'd have to do something like this:

var tifOptions = [];

Object.keys(tifs).forEach(function(key) {
    tifOptions.push(<option value={key}>{tifs[key]}</option>);
});

Update:

If you're writing ES6, you can accomplish the same thing a bit neater using an arrow function:

const tifOptions = Object.keys(tifs).map(key => 
    <option value={key}>{tifs[key]}</option>
)

Here's a fiddle showing all options mentioned above: https://jsfiddle.net/fs7sagep/

Upvotes: 247

alex1997
alex1997

Reputation: 431

I highly suggest you to use an array instead of an object if you're doing react itteration, this is a syntax I use it ofen.

const rooms = this.state.array.map((e, i) =>(<div key={i}>{e}</div>))

To use the element, just place {rooms} in your jsx.

Where e=elements of the arrays and i=index of the element. Read more here. If your looking for itteration, this is the way to do it.

Upvotes: -9

Related Questions