Reputation: 5798
I really don't know how to explain this problem, but I have the fiddles to help:
Only line 25 gets changed
CORRECT: http://jsfiddle.net/0maphg47/5/
var ListAnimate = React.createClass({
getInitialState: function() {
return {
list: [
{id: 1, caption: "Hello"},
{id: 2, caption: "There"},
{id: 3, caption: "Whatsup"},
{id: 4, caption: "Sanket"},
{id: 5, caption: "Sahu"}
]
};
},
shuffle: function() {
this.setState({ list: this.state.list.shuffle() });
},
render: function() {
// create a sorted version of the list
var sortedCopy = this.state.list.slice().sort(function(a, b) {
return a.id - b.id;
});
return <div>
<button onClick={this.shuffle}>Shuffle</button>
<ul>
{sortedCopy.map(function(el, i) {
// find the position of the element in the shuffled list
var pos = this.state.list.indexOf(el);
return <li key={el.id} style={ {top: (pos*60)+'px'} }>
{el.caption} {el.id}
</li>;
}, this)}
</ul>
</div>;
}
});
React.render(<ListAnimate />, document.body);
WRONG: http://jsfiddle.net/0maphg47/6/
var ListAnimate = React.createClass({
getInitialState: function() {
return {
list: [
{id: 1, caption: "Hello"},
{id: 2, caption: "There"},
{id: 3, caption: "Whatsup"},
{id: 4, caption: "Sanket"},
{id: 5, caption: "Sahu"}
]
};
},
shuffle: function() {
this.setState({ list: this.state.list.shuffle() });
},
render: function() {
// create a sorted version of the list
var sortedCopy = this.state.list.slice().sort(function(a, b) {
return a.id - b.id;
});
return <div>
<button onClick={this.shuffle}>Shuffle</button>
<ul>
{this.state.list.map(function(el, i) {
// find the position of the element in the shuffled list
var pos = this.state.list.indexOf(el);
return <li key={el.id} style={ {top: (pos*60)+'px'} }>
{el.caption} {el.id}
</li>;
}, this)}
</ul>
</div>;
}
});
React.render(<ListAnimate />, document.body);
Why do we have to render the li
objects in the same order every time if the key can determine uniqueness? I don't get why the order of the li
elements matter, but I'm probably missing something obvious
Upvotes: 1
Views: 385
Reputation: 6167
Take a look in the Elements view of your browser's debugger to see what is happening to the DOM when you click on the Shuffle button.
In the first (correct) case, the only thing that changes in the DOM is the style
attribute of each list item. The order and contents of the items don't change, only the appearance of the order changes. The element of key X was remains in the same position before and after the shuffle, so new DOM elements do not need to be created.
In the second (wrong) case, the actual order of the elements is shuffled. While key 1 may be in first position before the shuffle, it may in the fourth position after the shuffle. The attributes of the items are not being updated in place; rather, React may be creating new items where an item has changed positions. Hence, this can have an unpredictable effect on your transitions.
Upvotes: 1