Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: StrictMode reruns effects when a child is moved in an array #32561

Open
krispya opened this issue Mar 9, 2025 · 3 comments
Open

Bug: StrictMode reruns effects when a child is moved in an array #32561

krispya opened this issue Mar 9, 2025 · 3 comments
Labels
Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug

Comments

@krispya
Copy link

krispya commented Mar 9, 2025

With strict mode on in React 19, when a keyed React element is moved in an array its effects are rerun, even if they have no dependencies. The same behavior is not done for elements that stay in place. This is different from React 18 where moving an element did not trigger rerunning effects.

I would like confirmation if this is intended or a bug, but I did not see it documented so I assume it is a bug.

React version: 19.0.10

Steps To Reproduce

Here is a repro in React 19: https://stackblitz.com/edit/react-ts-qmpiwmru?file=App.tsx,index.tsx
And the same in React 18: https://stackblitz.com/edit/react-ts-pzgjq9ay?file=App.tsx

The current behavior

All effects are rerun when a keyed React element is moved in a child array.

The expected behavior

No effects are run, like React 18.

@krispya krispya added the Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug label Mar 9, 2025
@annous246
Copy link

I did run some tests ,

  • when you use only list reduction (reducedIds) in REACT 19 it dosent rerender ,
  • but when it comes to using only rotated ids with no reduction it rerenders ,
    • ->in my opinion new REACT 19 updates are much more strict on the virtual DOM comparaison on each change made to the order of keys per child element .

  • (this is evident when the last click that leaves you with the last child element dosent trigger a rerender due to elements order no changing after it),
    to prevent that "unecessary" rerender -> use mapping indexes as key values per element for order stability
function MapComponent({ ids }: { ids: number[] }) {
  return (
    <>
      {ids.map((id,index) => (
        <Item key={index} id={id} />
      ))}
    </>
  );
}

I hope This Helps ❤️

@krispya
Copy link
Author

krispya commented Mar 10, 2025

I did run some tests ,

* when you use only list reduction (reducedIds) in REACT 19 it dosent rerender ,

* but when it comes to using only rotated ids with no reduction it rerenders ,
  
  * ->in my opinion new REACT 19 updates are much more strict on the virtual DOM comparaison on each change made to the order of keys per child element  .

* **(this is evident when the last click that leaves you with the last child element dosent trigger a rerender due to elements order no changing after it)**, to prevent  that "unecessary" rerender -> use mapping indexes as key values per element for order stability
function MapComponent({ ids }: { ids: number[] }) {
  return (
    <>
      {ids.map((id,index) => (
        <Item key={index} id={id} />
      ))}
    </>
  );
}

I hope This Helps ❤️

I think this proves it is a bug as the fix you suggest is explicitly called out in the React docs as a pitfall because it creates unstable element-key references: https://react.dev/learn/rendering-lists#why-does-react-need-keys

If you dig into react-reconciler it has four kinds of actions it can take on keyed elements: insert, move, stay or delete. Stay does not cause effects to run mount, as you point out, but move does. Insert is a mount and delete is an unmount. I don't believe move should cause effects to mount, like it did in React 18, and this looks like a regression.

@totomakers
Copy link

Encounter the same issue. We have a Drag and drop list;

With React18 - the effect are not rerun - key is set to a static ID comming from API.
With React19 - effect are rerun

React 18 behavior:

output.webm

React 19 behavior:

output2.webm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug
Projects
None yet
Development

No branches or pull requests

3 participants