How to keep React state and db in sync with each other
I am making a like feature for a post where if user likes the post the counter increases on the ui and registers the like in db but sometimes the like counter goes into negative.
15 Replies
This won't solve the bug, but you could
Also, I'm curious if you're returning all the like/star objects just to check for their userId?
where do you mean?
If you’re returning all likes just to
map
and check for user id, then you could just do something like i am doing this
as im querying the post data, likes, comments and stars in one single request
Oh yes if the data is already there for other purposes from a single request, then yes. I would personally still use something to use a Prisma transaction or raw SQL to avoid reading & returning too much data. Something to worry about when you have many likes
thanks for the tip
will try to move to single queries after i get everything working properly
Just don't use state at all, it's not necessary.
how to do it then?
What you could do is set the like/follow button into a loading state and when the like succeeds you can update the state to the expected state
when refreshing the page you could then fetch it from the database
You should never try to sync local state with server state. The bug you're running into is an example of why you shouldn't. All state should be derived from the query data. Remove the useStates, only show the query data, and update it with optimistic updates https://tanstack.com/query/v4/docs/react/guides/optimistic-updates
Optimistic Updates | TanStack Query Docs
When you optimistically update your state before performing a mutation, there is a chance that the mutation will fail. In most of these failure cases, you can just trigger a refetch for your optimistic queries to revert them to their true server state. In some circumstances though, refetching may not work correctly and the mutation error could ...
I have an example with trpc here. Basically only use query data then invalidate(refetch) on successful mutation. You can use optimistic update with trpc as well which just wraps react query. Just an example btw, how I did it is probably not best practice.
https://github.com/Apestein/chirp/blob/main/src/components/Post.tsx
ahh i see thanks for this
yeah ill do that, just run a count query
because my schema has a likes table for the post likes
update: everythings working as expected
optimistic updates was the solution
do these many queries work properly with huge data?
Depends on what makes sense for your page.
Are all queries supposed to load on initial page load? If so, I'd try to minimize the number of requests, at least to avoid latency issues.
For example, if I'll always need to see whether a post is liked once it loads, I'd just include isLiked, isStarred, countComments in the post request (especially since it's really easy with tRPC's
context.session
).
Other details may only be needed when the user interacts with the post, like seeing the actual comments and the name/photo of commenters, so they can be their own requests and wait until called.
Optimistic updates are also awesome for comments. You may want to show the comment UI feedback without waiting for it to be on the databasethanks for the tips 🤝
@Apestein hey i was trying to implement infinite scrolling and saw your implementation, but its not working properly. It just keeps on loading forever