-
-
Notifications
You must be signed in to change notification settings - Fork 3k
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
setQueryData not re-rendering the React Component #1535
Comments
The issue seems to be that useState doesn’t trigger a re-render if the value in the state is the same as the current value in the state. It works just fine if you enter a different text and press the Button. |
@TkDodo the |
yes, it should and it does. if you remove I'm not really sure why the interaction of local state + setQueryData causes this behaviour 🤔 . Here would be an even more minimal reproduction of the issue: https://codesandbox.io/s/queryclientsetquerydata-no-re-render-forked-0gx3k?file=/src/App.tsx
So it seems to only occur if you have local state that is also set to exactly the value that we currently have in the state... |
Thanks @TkDodo I'm aware that removing |
After executing the |
Thanks @boschni. I now have a clearer picture of the issue. |
I hope this issue gets fixed soon as it took me quite a bit of time to debug why the components weren't re-rendering.
But this doesn't:
|
@utkarshgupta137 your example has nothing to do with the issue i believe. Please don’t mutate existing cache values but return a new object / array instead. You can also use |
For anyone who is facing issues with setQueryData not re-rendering the React Component Make sure you really update the data inside query client immutalbe! My example:
Use instead something like this:
|
@mleister97 please make a PR to the docs if you think we could highlight this more |
thanks guys, this series of posts helped me to fix an issue when deleting an item from a list of infinite items fetched using Now I'm seeing a weird behaviour that not sure if its related or should be in a different issue and is, after updating the cache using |
this sounds like the item hasn't really been deleted in the backend if a refetch brings it right back ... |
I can confirm the backend is working as intented, actually noticed this is happening to other item updates as well, like changing values to properties from true to false or viceversa, that apparently its working, because the state is updated and the changes are reflected in the frontend, but same story, with the refetch, all changes prior to my update come back. I haven't mentioned this is a RN project with no hydratation, but shouldn't change anything, right? Seems I need to investigate this further using a new project that I can share. |
after running some local tests with web vs mobile (using the same base code), noticed the web version was working fine all the time whereas the mobile was having something odd. for some reason, the api call from the mobile was always re-rendering deleted items (server and from query-cache), axios apparently was doing the requests but the server never recieved the request event, so in the end, decided to add a random value to the url and this did the trick, so now everytime the refetch is triggered, the requests is received by the server and data is refreshed according to last version. so the question now is if there's any relation between these ends (axios, react-query) and this behaviour? also, adding this random value at the end of the url could cause any other issue? thanks @TkDodo |
Thanks mleister97 , I was doing the same mistake, wasted 3 hours till I found your reply 👍 |
@TkDodo im having a similar issue very similar to #1535 (comment)
I make the call to Whats also interesting if i split the functions like so.
It re-renders properly if i await the call to react query OR i wrap the Which im not happy about both. So im wondering if something is architected fundamentally wrong and we should fix that issue instead of forcing this to work. This has nothing to do with JS object immutability Thanks! |
The reproduction from that time is no longer "broken": It works fine in v4: https://codesandbox.io/s/queryclientsetquerydata-no-re-render-forked-0gx3k?file=/src/App.tsx My guess is because we now |
Thank you so much for the quick reply and response. Will bump if im still seeing issues. |
@TkDodo the upgrade didnt seem to fix my issue. I have a virtualized table with items (fetched from react-query) and bulk update state (checkboxes when I store a list of ids in provider state) When I select an item in the table and then delete that item
But it looks like the provider state update is winning every time, the component is being re-rendered and the item is undefined and breaks the ui. The docs say Like in my previous comment, awaiting on the function that calls setQueryData fixes the issue but feels "dirty". I fixed it by just guarding in the component. Tried to build a sandbox and repro but couldnt in a test env. Let me know if you have any thoughts or ideas. Thanks |
I was facing the same issue in one of my production ready app where i was utilizing react query a lot. Whenever, I made update with It was a headache for me as I wasn't going to replace the whole logic with global state(redux/recoil/context) and not even calling API again. What i did is created a state
and then use this as a key to the parent container from where I was passing down the data to children something like below I update the key as soon i call
`
`
|
@codestacx thats probably not ideal, youre forcing the key to change which is why the re-render is happening. You might have an immutability issue. Dont know if you wanna share the code in github. |
@scottstern I believe I'm having the same issue outline above or at least similar symptoms. I haven't tried splitting setQueryData to another function that I await but if that were to work, I would also agree with your "dirty" comment. In my case, I'm calling I'm returning a new Array by spreading the old one after modifying it but the new data is not triggering a state change in the component where I have the Even if I trigger a render of the component through other means it's failing to trigger a useEffect which contains the data from For the time being I'm using |
don't modify it! It's not an immutable update if you modify the source. Just spreading the top level doesn't make it an immutable update ... |
Thanks @TkDodo I was witting a new comment where I discovered that. I think that's where I was going wrong. I modified my code to prevent modifying the |
Thanks a lot, comment #1535 (comment) really did it for me. |
I think there are two seperate issues here. I'm not manipulating the old data in any way, just completely replacing it entirely and I'm seeing the same behavior, whether I use put it in onSuccess or in the mutationFn. `const { data: cartItems, dataUpdatedAt } = useGetCart()
cartItems alone will not trigger this, but with dataUpdatedAt, it works fine as mentioned above. |
Issue:
I'm running
setQueryData
to update query data while also updating the internal state of the component. This causes the component to not re-render after the change in query dataInside React component
To Reproduce
Refer the codesandbox
The text was updated successfully, but these errors were encountered: