reactjsreactcsstransitiongroupreact-transition-group

Getting warning about unique "key" when trying to import ReactCSSTransitionGroup into react app


I hope somebody could shed some light into this issue. After many attempts, I was able to import ReactCSSTransitionGroup into my react app correctly. Now I'm getting the following warning and my transition is not working.

Warning: Each child in an array or iterator should have a unique "key" prop.

I wrapped my component in the main App.js file with the ReactCSSTransitionGroup element like this.

return (
  <div className="container">
    <Navigation />
        <div className="app-items-container">
            {
            this.state.notes.map((note) => {
                return(
                    <ReactCSSTransitionGroup {...transitionOptions}>
                        <Note noteContent={note.noteContent} 
                        noteId={note.id} 
                        key={note.id} 
                        removeNote={this.removeNote} />
                    </ReactCSSTransitionGroup>
                    )
                })
            }
        </div>
    <Form addNote={this.addNote} />
  </div>
);

My component already has a key passed to it. Where should I apply the key?


Solution

  • I don't think you want the ReactCSSTransitionGroup inside the .map function. It should be outside and ReactCSSTransitionGroup will add it's magic to each of it's children (your Note component).

    It works by adding additional lifecycle methods to 'each' of it's children as they are added/removed from the DOM. So there is no need to wrap each of the Note components with ReactCSSTransitionGroup, it should simply have all the Notes as it's children.

    The key warning is because ReactCSSTransitionGroup will wrap it's children in a span. When in the .map loop, react will see something like the following:

    <span> <Note key={note.id} /> </span>
    <span> <Note key={note.id} /> </span>
    <span> <Note key={note.id} /> </span>
    

    React will want each of the spans to have a unique key, the child Note key will be ignored.

    Moving it outside the map will give you this:

    <span> 
        <Note key={note.id} />
        <Note key={note.id} />
        <Note key={note.id} />
    </span>
    

    And React will be happy as each Note has a key.

    Try the following:

    return (
      <div className="container">
        <Navigation />
            <div className="app-items-container">
               <ReactCSSTransitionGroup {...transitionOptions}>
                 {this.state.notes.map((note) => {
                    return(
                            <Note noteContent={note.noteContent} 
                            noteId={note.id} 
                            key={note.id} 
                            removeNote={this.removeNote} />
                        )
                    })
                  }
                </ReactCSSTransitionGroup>
            </div>
        <Form addNote={this.addNote} />
      </div>
    );