react icon indicating copy to clipboard operation
react copied to clipboard

[React 19] React 19 runs extra effects when elements are reordered

Open devongovett opened this issue 1 month ago • 0 comments

Summary

When React elements with stable keys are reordered with no other prop changes, React 19 re-runs their effects even though dependencies have not changed. This did not occur in React 18. In addition, this only happens for some of the elements, and not others. As far as we can tell, when reordering an earlier element to be later, the earlier element's effects are run, and the later element's are not. When reordering a later element to be earlier, no effects are run. In React 18, no effects are run in either case.

The below code sandboxes swap the keys of two elements to simulate re-ordering. When the keys are swapped, the first element's effects run but the second's do not. In React 18, no effects are run.

We think React 18's behavior is correct: since no dependencies have changed and the component is not being unmounted and remounted, it should not call any effects.

Note that this only happens in strict mode. Without strict mode, no effects are run.

Steps:

  • Open sandbox and open console.
  • After initial load, clear the js console.
  • Click the swap button.

Note that the effects run for the first element, but not the second.

It appears this changed between the last 18.3 canary, and the first 19 canary:

Context

We noticed this in our tests while upgrading React Aria to React 19. However, it does not only occur in tests, it also occurs in development builds in browser. Specifically, we are seeing this in our drag and drop implementation, where users can drag to reorder elements in a list. The extra effects are causing our code to emit additional events compared with React 18.

cc. @LFDanLu @snowystinger

devongovett avatar May 25 '24 00:05 devongovett