React CSSTransitionGroup deleted item shifted to end
Asked Answered
A

1

1

I'm using the CSSTransitionGroup addon to animate the addition and removal of items to an array. When adding, the animation performs as expected, but on remove the removed item is shifted to the end before the animation begins. I'm fairly new to React, butI assume there is something going on under the hood with how React reconciles array changes?

http://jsfiddle.net/alalonde/0kztn19d

Anarchist answered 14/3, 2016 at 4:50 Comment(2)
In your fiddle, I get different behavior: header slides in from top on first render, and when toggling 1st/ 2nd link, the page dissapears en then the other fades in (without animation). There is no adding or removing functions I can find.Ankeny
Oops, wrong fiddle! Thanks for pointing that out.Anarchist
A
1

Your remove statement goes wrong because of react's key specifics. See explanation here of dynamic components (which is what you have), and how to use them with 'key`.

To repair, change your return statement inside the mapping of children to:

return <Item key={item} item={item}/>;

And create a new (pure) component called <Item>:

var Item = React.createClass({
  render: function() {
    return <div>{this.props.item}</div>;
  }
});

I tried this in your fiddle and it works. Hopefully this link will give you the updated fiddle.

BTW: In line with fiddle, my changes are quick and dirty solution: react expects keys to be unique AND related to the content of the item in the list. My example does meet the second requirement (Please do NOT use the mapping index as the key), but it fails on the first: if you add, then delete, then add, the example code would produce a next item with the same number (not unique), so it fails.

Ankeny answered 14/3, 2016 at 17:16 Comment(2)
This got me on the right track. The key (har har) is that keys must be unique ACROSS render passes. This is why using an index does not work -- if the index changes between renders (as in a remove op), it is no longer a valid key.Anarchist
Although it will work, having keys unique across renders is very inefficient. Keys must be unique to the item they display: the same item should have the same key in different render passes. (even if it is at different position in the list). See my answer to a related question hereAnkeny

© 2022 - 2024 — McMap. All rights reserved.