The below snippet has four boxes. The purpose is that these boxes order will be shuffled and a transition animation occurs as they go to a new location. Each box's key corresponds with a color value from the source array in useState. Each update via the shuffle button, the source array's values are shuffled. Then I map through the array in the return function. I set 2 classNames for each box. One classname corresponds with the index and is for positioning. The other classname corresponds with the source array value and is always in unison with the key for that box.
My issue is that react seems to randomly be deciding what keys to pay attention to and reconcile, and what keys to disregard and just remount those elements. You can see here, some elements properly transition while others just jump to their target location. I'm at a loss as to why this is occuring. Can someone help?
EDIT: I don't believe this is a reconcile issue with respect to unwanted remounting. React is properly respecting the keys and not remounting any. So the issue is with how React handles CSS transition classes added during updates. Some transitions work and others don't. It may just be a limitation of the engine, but if anyone has any further incite please share.
const {useState} = React;
function App() {
const [state, setState] = useState(['Red', 'Green', 'Blue', 'Black'])
function handleShuffle() {
const newState = _.shuffle(state)
setState(newState)
}
return (
<div className="App">
{state.map((sourceValue, index) => {
return (
<div className={
'box positionAt' + index + ' sourceValue' + sourceValue
}
key={sourceValue} ></div>
)
})}
<button id="shuffle" onClick={handleShuffle}> shuffle < /button>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render( <
App / > ,
rootElement
);
.App {
position: relative;
width: 200px;
height: 200px;
background-color: gray;
}
.box {
width: 25px;
height: 25px;
position: absolute;
transition: transform 1s;
}
.positionAt0 {
transform: translate(0px, 0px);
}
.positionAt1 {
transform: translate(175px, 0px);
}
.positionAt2 {
transform: translate(0px, 175px);
}
.positionAt3 {
transform: translate(175px, 175px);
}
.sourceValueGreen {
background-color: green;
}
.sourceValueBlue {
background-color: blue;
}
.sourceValueRed {
background-color: red;
}
.sourceValueBlack {
background-color: black;
}
#shuffle {
position: absolute;
top: 0px;
left: 75px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>
<div id="root"></div>