Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swapping Keys Still Introduces Fresh DOM Element

Tags:

reactjs

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;
}
like image 217
fweth Avatar asked Jan 22 '26 03:01

fweth


1 Answers

It's not a React issue, it's a DOM issue. There is no way in the DOM API to swap two nodes, the only way to do it is to remove one of them and then insert it again at a different place, so that's what React is forced to do.

You need to find a different way to do it, for instance by swapping the classes and the contents instead of trying to swap the elements.

like image 195
Guillaume Brunerie Avatar answered Jan 24 '26 19:01

Guillaume Brunerie



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!