richbai90
richbai90

Reputation: 5204

React: Encountered two children with the same key

I'm trying to follow a tutorial on React and part of the exercise is to build my own cycling boxes component using states to toggle which box is selected. I've set my code up like so

var Board = React.createClass({
      render: function() {
        var className = "board";
        if (this.props.selected) {
          className += " selected";
        }
        return ( < div className = {
          className
        } > {
          this.props.index + 1
        } < /div>
    );
  }
});

var BoardSwitcher = React.createClass({
  boards: [],
  toggleStateSelection: function() {
    var self = this;
    this.setState({
      selected: function(){
        if (self.state.selected + 1 < self.boards.length) {
            return self.state.selected + 1;
        } else {
            return 0;
        }
      }()
    })
  },
  getInitialState: function () {
    return {
      selected: 0
    }
  },
  render: function() {
    for (var ii = 0; ii < this.props.numBoards; ii++) {
      var isSelected = ii === this.state.selected;
      this.boards.push(
        <Board index={ii} selected={isSelected} key={ii} / > );
      }

        return ( < div >
        < div className = "boards" > {
          this.boards
        } < /div>
        <button onClick={this.toggleStateSelection}>Toggle</button >
        < /div>
    );
  }
});

React.render(
  <BoardSwitcher numBoards={4} / > ,
        document.body
      );

But I keep getting the error

Warning: flattenChildren(...): Encountered two children with the same key, `.$0`. 
Child keys must be unique; when two children share a key, only the first child will be used. 

I think the problem might be that I need to somehow clear the array before I do anything else, but when doing that, although it stops the error, the selection still does not change.

Here is a jsbin of the problem

http://jsbin.com/hakisoyuli/1/edit?js,console,output

Upvotes: 2

Views: 2951

Answers (1)

Brigand
Brigand

Reputation: 86260

You have this.boards which is an array that gets 4 elements pushed onto it each time render runs. Instead use a local variable boards that you initialize to an empty array.

var boards = [];
for (...) { ... };
return <div>{boards}</div>

Upvotes: 1

Related Questions