In this example, the key of the two elements are swapped, so in theory, there should be a transition on both elements, as they change opacity. But apparently, React only keeps one element, and replaces the other by a fresh one. Is this a bug or do I miss something about the semantics of the key property?
Here is a version where I use an effect for the updates, to illustrate what I wanted to achive. I wonder if this is nicer anyway, since I don't have the oldIndex state.
JSX:
export default function App() {
const [index, setIndex] = useState(0);
const [oldIndex, setOldIndex] = useState();
const [toggle, setToggle] = useState(0);
const clickHandler = useCallback(
(d) =>
function () {
setOldIndex(index);
setIndex(index + d);
setToggle(1 - toggle);
},
[index, toggle]
);
return (
<div className="App">
<button onClick={clickHandler(-1)}>Decrease</button>
<button onClick={clickHandler(1)}>Increase</button>
<h1 className="active" key={1 - toggle}>
{index}
</h1>
<h1 className="inactive" key={toggle}>
{oldIndex}
</h1>
</div>
);
}
CSS:
.App {
font-family: sans-serif;
text-align: center;
}
h1 {
position: absolute;
width: 100%;
transition: opacity 2000ms;
}
h1.inactive {
opacity: 0;
}