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

Unexpected re-rendering components when update state #7852

Closed
hiep294 opened this issue Aug 5, 2024 · 3 comments
Closed

Unexpected re-rendering components when update state #7852

hiep294 opened this issue Aug 5, 2024 · 3 comments

Comments

@hiep294
Copy link

hiep294 commented Aug 5, 2024

Describe the bug

When removing or adding an item of list, by queryClient.setQueryData, then some other items' components are also re-rendered. I make sure that components are wrapped with React.memo. If remove the 1st item, then 2nd,3rd,... will be re-rendered. If remove the 3rd item, then 4th,5th will be re-rendered

Your minimal, reproducible example

https://codesandbox.io/p/sandbox/memo-testing-react-query-kclcgq

Steps to reproduce

  1. Open Browser Dev Tool
  2. Delete 1st post
  3. Look at that other post components are re-rendered, and show the message in the Browser Dev Tool

Expected behavior

As a user, I expect when changing (delete, add,...) an item in list with queryClient.setQueryData, other items' components will not be re-rendered

Screenshots or Videos

1st
2

Tanstack Query adapter

react-query

TanStack Query version

5.51.21

TypeScript version

5.5.4

@TkDodo
Copy link
Collaborator

TkDodo commented Aug 6, 2024

interesting. seems to be related to replies (removing the prop makes the re-renders go away) and structuralSharing. Setting that to false also makes them go away.

I think what happens is that with structuralSharing, we try to keep as many references from previously cached values as possible. So when you delete element 3, element 4 moves into the position of element 3. Then, we try to re-use that object in that position, but because it contains new data, it has to become a new object. Since you destruct name and id, those are primitives so it doesn't matter, but when it comes to replies, it's a new array instance (because again, values have changed inside for that position).

We cannot "take over" the element from the next position because we don't know how they relate. You won't see the problem with react state and lists, because react keeps track of elements with a special key, and when it sees the same key, it re-uses the element with that key. But we don't have that information, so there isn't anything we can do here.

You can:

@TkDodo TkDodo closed this as not planned Won't fix, can't repro, duplicate, stale Aug 6, 2024
@hiep294
Copy link
Author

hiep294 commented Aug 7, 2024

Thank you for the work around idea, can you check the permission access of your codesanbox link ?

@TkDodo
Copy link
Collaborator

TkDodo commented Aug 9, 2024

sorry about that. updated it 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants