useEffect not triggered when data change
I have this :
When my
playlistItems
change I can see the first console.log
but the one in useEffect
isnt triggered.. why ? I check that because I have a react table showing playlistItems
but the table isnt updated when fresh data arrived...
Thx for your help !28 Replies
correct-apricot•10mo ago
It's because of the way useEffect works. It doesn't work if you pass an array as the dependency
foreign-sapphire•10mo ago
Hi, can you show us
usePlaylistItems
please?harsh-harlequinOP•10mo ago
ohh yes its working with
playlistItems.length
as depency
TO prevet making multiple requests I do this for getting the playlist :
SO here I manually set Query data for playlistItems for making only one requst. But the usePlayItems do this for being invalidate (only items) :
So my problem seems to be with React Table
Because with this :
PLaylistItems is updated in realtime, but it seems when playlistItems
change, the table dont change. I dont really know what to do for updating the tableforeign-sapphire•10mo ago
It's not a problem with array as a dependency. It's a reference problem. One thing that can cause this issue is this one
foreign-sapphire•10mo ago
React Query Render Optimizations
An advanced guide to minimize component re-renderings when using React Query
harsh-harlequinOP•10mo ago
I dont really understand because my key dont change for items. I probably miss understand the post but my key is :
['playlist', id, 'items']
. WHen I receive realtime change i do this :
Items are associated to a playlist id
foreign-sapphire•10mo ago
The key is ok.
Try to set
structuralSharing: false
on usePlaylistItems
and see if it changes anything.harsh-harlequinOP•10mo ago
Ohh its working now
But do using
structuralSharing: false
can cause issue ?foreign-sapphire•10mo ago
It's an optimization mechanism that combines oldData and newData and only changes items that are different. If you have a deeply nested object or array, this may sometimes lead to unpredicted behavior.
Frankly speaking, it's not a necessity, it's only an optimization technique, so it shouldn't break anything if you turn it off.
harsh-harlequinOP•10mo ago
I dont really understand this structual sharing here, because I update the entire items with for one specific playlist
id
. I probably miss something, but in the example here there is multiple id of todoharsh-harlequinOP•10mo ago
There is a way to optmise speed when updating react query data ?
Because doing this :
Is not smouth :
harsh-harlequinOP•10mo ago
Doing this instead with local state :
foreign-sapphire•10mo ago
It's hard to say. Optimization techniques will differ depending on your code structure. There's no one solution to this, every case is different and requires a closer look. You need to profile your app and see bottlenecks, then address them one by one. Maybe too many components are dependent on PlaylistItems and they all rerender at the same time, maybe you need to move use playlist items closer to where you need them, to not cause rerenders higher up in the component tree, like you did with a local state.
harsh-harlequinOP•10mo ago
That weird ebcause my
usePlaylistItems
is only use one time 😅foreign-sapphire•10mo ago

foreign-sapphire•10mo ago

harsh-harlequinOP•10mo ago
I only use this for being able to invalidate items when I add one from another page 😅
foreign-sapphire•10mo ago
Why don't you invalidate query by a key, to save 1 request? Premature optimization is the root of all evil 😅
harsh-harlequinOP•10mo ago
What do u means query by query ? When I add movie to a playlist, I invalidate the
['playlist', id, 'items']
key
Or u means invalidate directly ['playlist', id]
foreign-sapphire•10mo ago
Instead of doing
queryClient.setQueryData
you may do queryClient.invalidateQueries({ queryKey: ['playlist', id, 'items'] })
foreign-sapphire•10mo ago
Mastering Mutations in React Query
Learn all about the concept of performing side effects on the server with React Query.
foreign-sapphire•10mo ago
This article explains the difference between the two and when you should use one over the other.
harsh-harlequinOP•10mo ago
Well when I dont need to query the database, like change the rank of an item, I use
setQueryData
, when I add a movie to the playlist from outside of the palylist page I use invalidateQueries
and when I receive realtime event change, I only query the new items and add it to the list with setQueryData
. I dont know if its a good way to do it but its for optimise my backend requestforeign-sapphire•10mo ago
That's what I'm talking about. You are doing it manually with a
setQueryData
to save a few requests. Most of the time you want to use invalidateQueries
with a key. It doesn't make an immediate request if no component is watching this query. It will fire a new request when components that use this query mount on the page. setQueryData
sets data directly to the cache, but it doesn't prevent the request from firing if you don't configure staleTime. So you don't save any requests in this case. Of course, I don't see the full picture, maybe you set staleTime, and requests actually don't fire after setQueryData, but in general, this method should be used in very specific cases. Not only it take more code to write setQueryData than invalidateQuery, but it also does not provide any benefits if done wrong.harsh-harlequinOP•10mo ago
Tell me if Im wrong but in my case, when I use
setQueryData
that means the element is already show in page. For example in playlist page where items are rendered. I have a button for example to delete an item. This button gonna make a query to my db to delete this item. And for not refetch the entire playlist, I use setQueryData
to delete manually in my list of items the concerned one. If I use invalidateQueries
its gonna refetch the entire playlist right ?foreign-sapphire•10mo ago
Yes. What you describe is a good case for optimistic update. But don't worry to much about your requests or querying the DB. DB is millions times faster then BE, and BE is generally faster than FE. So in this case you should worry about your UI working smoothly, not the BE optimization
harsh-harlequinOP•10mo ago
Yeah ahah but my db is sometime kinda slow (Im self hosting Supabase) so I wanna optimise some query
For the changing rank, I find something, using queryCache for items but also local state for the rendering:
Its working ahah
foreign-sapphire•10mo ago
Don't get me wrong, there's no right or wrong here. I'm just giving you another perspective on a matter. It's all trade-offs. If you see that in your case using setQueryData is beneficial then go for it. I'm just saying that maybe you should try to consider a different approach. Maybe adding some pagination to playlistItem to get data in smaller portions to not overload your DB, or optimizing the data structure will help you get the best of both worlds 🙂
As I've told you, the specific approach to optimization will depend on a number of factors.