11

Please help me. I don't know why this piece of code doesn't work.

It gives me an error: "Objects are not valid as a React child (found: object with keys {itemss}). If you meant to render a collection of children, use an array instead." Why {i.title} is an object. It's just a string. How can i fix this? and How actually I can iterate nested objects?

class ShopItem extends React.Component {

render() {
    var items = [
        {
            link: 'first link',
            title: 'Emery NEM XF',
            price: '$950'
        },
        {
            link: 'second link',
            title: 'Emery NEM XF',
            price: '$950'
        },
        {
            link: 'third link',
            title: 'Emery NEM XF',
            price: '$950'
        }
    ];


     const item = items.map((i) =>{

          return ( <h1>{i.title}</h1> )
    });

        return (
            {items} 
        )
  }
}

ReactDOM.render(<ShopItem /> , document.querySelector('#root'));
Alexander
  • 113
  • 1
  • 1
  • 5

4 Answers4

15

The problem is because you return

return (
        {items} 
    )

which is an equivalent of return ({items: items}) ie. you are returning an object with key items and React doesn't expect objects for rendering. You could either write

   const items = items.map((i) =>{
      return ( <h1>{i.title}</h1> )
   });

   return items;

or

     return items.map((i) =>{
        return ( <h1>{i.title}</h1> )
     });

or

  const items = items.map((i) =>{
      return ( <h1>{i.title}</h1> )
   });

  return <React.Fragment>
        {items} 
    </React.Fragment>

P.S. Note that the first two approaches will work from react v16.0.0 onwards while the last will work from v16.2 onwards.

However if you are using a lower version, you would need to wrap the return element within a container like

    return (
        <div>{items}</div> 
    )
Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400
1
return (
        {items} 
    )
  1. In the above line, you render the "items" list. You should render the "item" list which you have create from the map function of the "items" list.

  2. And you should be render it into an element.

    class ShopItem extends React.Component {

    render() { var items = [ { link: 'first link', title: 'Emery NEM XF', price: '$950' }, { link: 'second link', title: 'Emery NEM XF', price: '$950' }, { link: 'third link', title: 'Emery NEM XF', price: '$950' } ];

     const item = items.map((i) =>{
    
          return ( <h1>{i.title}</h1> )
    });
    
    return (
        <div>
        {item} 
        </div>
    )
    

    } }

ReactDOM.render( , document.querySelector('#root'));

SOUser
  • 44
  • 7
0

You need to wrap items in JSX in your return statement:

return (
    <React.Fragment>
        {items}
    </React.Fragment>
)

Your final return statement currently is not inside JSX. It's plain old JavaScript that is constructing an object like {items: items} thanks to enhanced object literals, which is why React is saying you are giving it an item with key items.

Ross Allen
  • 43,772
  • 14
  • 97
  • 95
0

here you go:

return (
    <div>
        {items.map(i) => (
            <h1>{i.title}</h1>
        )}
    </div>
)

edit: in react, return/render can not have a structure like

<h1>{i.title}</h1>
<h1>{i.title}</h1>
<h1>{i.title}</h1>

you should wrap them in a <div> or another element. also you JS was wrong which I corrected

Luna
  • 1,168
  • 8
  • 17
  • The function you pass to `map` should either use curly brackets or remove the `return` keyword. Right now it's invalid syntax. – Ross Allen May 08 '18 at 10:20
  • 1
    @RossAllen correct, it was a quick write. didn't pay attention. will edit – Luna May 08 '18 at 10:22