Below codes is for animating components.
listItem statesAnimationText re-rendered, so animation occursconst AnimationText = styled.div`
/* ... */
animation: ${SlideUpAnimation} 750ms ease forwards;
`;
// this code works (success animate)
const BestCocktailList = () => {
const [listItem, setListItem] = useState<BestCocktail[]>(...);
const [itemIdx, setItemIdx] = useState<{ old: number; new: number }>(...);
useEffect(() => {
// change state every 3 seconds
setInterval(() => {
setItemIdx((prev) => ({ old: prev.new, new: (prev.new + 1) % (listItem.length) }));
}, 3000);
// more codes..
}, [listItem]);
return (
// ...
<AnimationContainer>
<AnimationText key={`o_${itemIdx.old}`}>
{listItem[itemIdx.old].name}
</AnimationText>
<AnimationText key={`n_${itemIdx.new}`}>
{listItem[itemIdx.new].name}
</AnimationText>
</AnimationContainer>
);
}
I understood why above code works correctly. React knows the difference of element tree because of changing key props.
But I can't understand why below codes are not working.
// do not works (failed animate)
const BestCocktailList = () => {
// ...
return (
// ...
<AnimationContainer>
<AnimationText>
{listItem[itemIdx.old].name}
</AnimationText>
<AnimationText>
{listItem[itemIdx.new].name}
</AnimationText>
</AnimationContainer>
);
}
The Difference is usage of key props.
// success
<AnimationText key={some key}/>
// fail
<AnimationText/>
if there is no key props, React looks from top to bottom for finding difference (just my knowledge). And it is obiously different element I think (like below)!
// before
[
{ type: 'div', props: { children: listItem[0].name }},
{ type: 'div', props: { children: listItem[1].name }}
]
// after
[
{ type: 'div', props: { children: listItem[1].name }},
{ type: 'div', props: { children: listItem[2].name }}
]
Then why animation not working?