0

I have a list of items I am rendering inside my render method (conveniently, actually named Item).

    render() {
        return (
            <div>
                {
                    this.state.items.map(item => (
                        <Item
                            id={item.id}
                            myValue={item.myValue}
                            updateItem={this.handleUpdateItem}
                            deleteItem={this.handleDeleteItem}
                        />
                    ))
                }
            </div>
        )
    }

This works, but I get the warning that Each child in a list should have a unique "key" prop. However, adding the key prop causes an error.

  render() {
        return (
            <div>
                {
                    this.state.items.map(item => (
                        <Item
                            id={item.id}
                            key={item.id}
                            myValue={item.myValue}
                            updateItem={this.handleUpdateItem}
                            deleteItem={this.handleDeleteItem}
                        />
                    ))
                }
            </div>
        )
    }

The error:

Uncaught Invariant Violation: Objects are not valid as a React child (found: object with keys {myValue}). If you meant to render a collection of children, use an array instead.

This error only happens on update, when I change the myValue of an item. The initial page loads just fine.

Could someone help me understand what's going on here?

John Hinnegan
  • 5,864
  • 2
  • 48
  • 64
  • 1
    I can't see anything immediately wrong with what you have, but React is clearly saying that somewhere a component is returning an Object from a `render` call. Does the `Item` component render any child components? What does `Item` do with the `myValue` prop? Any chance of recreating the issue in a [StackBlitz](https://stackblitz.com) or similar? – Jono Job Jun 05 '19 at 01:45
  • 1
    A [question/answer](https://stackoverflow.com/a/33577681/4289902) for a similar issue – Jono Job Jun 05 '19 at 01:48
  • I found that one, wasn't able to identify which case was causing my issue. – John Hinnegan Jun 05 '19 at 02:03
  • I pushed the code to github https://github.com/softwaregravy/react_learning_todo – John Hinnegan Jun 05 '19 at 02:03

2 Answers2

1

1st err

may be you state.items like [{id: "value0"}, {id: "value1"}, {id: "value0"}] duplicate key "value0", you can use key={index} instead of key={item.id}

this.state.items.map((item, index) => (
   <Item
       id={item.id}
       key={index}
       myValue={item.myValue}
       updateItem={this.handleUpdateItem}
       deleteItem={this.handleDeleteItem}
    />
))

2nd err

your Item maybe like

function Item({myValue}){
   return <div>{myValue}</div>
}

but your state.items looks like

[
 {id: "id", myValue: "this is correct"}, 
 {id: "id2", myValue: {myValue: "this is incorrect value"}}
]
欧阳斌
  • 2,231
  • 1
  • 8
  • 8
  • Neither of these is my issue, unfortunately. I have unique keys (generated by uuid) and I logged out my update value, and don't have an object there, just the string, your "this is correct" case – John Hinnegan Jun 05 '19 at 01:48
1

So when I run your code, the full error text is:

Objects are not valid as a React child (found: object with keys {myValue}). If you meant to render a collection of children, use an array instead.
in div (created by Item)
in div (created by Item)
in Item (created by ItemList)
in div (created by ItemList)
in ItemList (created by App)
in div (created by App)
in App

Using the stack trace, we can see that this is being caused within the Item component. Going further, this is the code that ends up within two divs:

let display =
  <div>
    {this.state.displayValue}
    <button onClick={this.handleEdit}>Edit</button>
    <button onClick={this.handleDelete}>Delete</button>
  </div>

The rendering of this.state.displayValue is causing the error. Using a console.log, it shows that after an update, displayValue is set to an object.

I'll let you chase up why that's happening :)

Jono Job
  • 2,732
  • 1
  • 23
  • 23