T
TanStack•3y ago
correct-apricot

How to prevent data from sorting after refetch

Hi, i have a function to like a specific publication that i'm using as
export const useUpdatePost = () => {
const queryClient = useQueryClient();
return useMutation((payload: any) => updatePost(payload), {
onSuccess: () => {
queryClient.invalidateQueries(["posts"]);
},
});
};
export const useUpdatePost = () => {
const queryClient = useQueryClient();
return useMutation((payload: any) => updatePost(payload), {
onSuccess: () => {
queryClient.invalidateQueries(["posts"]);
},
});
};
And this is working fine, the problem is that after it refetches the order of the data changes, so let's say i like the first publication and when it refetches onSuccess, the first post will appear in the middle, as the second post, or as the last post. How can i prevent that?
12 Replies
conscious-sapphire
conscious-sapphire•3y ago
not quite sure what you mean. react-query gives you the data the way it is returned from the queryFn. That is likely how your server sends it. The way things are sorted are entirely up to you. You can also re-sort it differently before rendering it ...
correct-apricot
correct-apricotOP•3y ago
As you said, the order is changing on the server. Is there a way to, after the mutation i just update an specific item from 'posts'? I was reading your blog about mutations, and i think that's my way to go, but for some reason it's not updating my screen I'm getting the posts like this
export const usePosts = () => {
return useQuery(["posts", "id"], getPosts);
};
export const usePosts = () => {
return useQuery(["posts", "id"], getPosts);
};
And i'm mutating with this
export const useUpdatePost = () => {
const queryClient = useQueryClient();
return useMutation((payload: any) => updatePost(payload), {
onSuccess: (updatedPost) => {
console.log(updatedPost);
queryClient.setQueryData(["posts", updatedPost.id], updatedPost);
},
});
};
export const useUpdatePost = () => {
const queryClient = useQueryClient();
return useMutation((payload: any) => updatePost(payload), {
onSuccess: (updatedPost) => {
console.log(updatedPost);
queryClient.setQueryData(["posts", updatedPost.id], updatedPost);
},
});
};
What am i doing wrong here?
conscious-sapphire
conscious-sapphire•3y ago
Looks about right
correct-apricot
correct-apricotOP•3y ago
I was checking the dev tools and it's showing this
No description
correct-apricot
correct-apricotOP•3y ago
Should it appear as inactive?
conscious-sapphire
conscious-sapphire•3y ago
inactive means it's not used. you use ["posts", "id"]. I don't think you'd want the string "id" but the actual id in there? (see the second line in the devtools)
correct-apricot
correct-apricotOP•3y ago
But in order to update the post with the id, isn't the "id" key necessary?
correct-apricot
correct-apricotOP•3y ago
I took of the id key off, but still
No description
conscious-sapphire
conscious-sapphire•3y ago
okay I don't fully understand what you're trying to do, and screenshots don't help. am I right that you have a list of things, and then you make an update to ONE thing in the list and want to update it inside the list?
correct-apricot
correct-apricotOP•3y ago
Yes, i want to update just one thing and then bring the client side up to date
conscious-sapphire
conscious-sapphire•3y ago
so then you have to write back to the list query. if your list query is "posts", something like:
queryClient.setQueryData(
["posts"],
(prev) => prev.map(post => post.id === updatedPost.id ? updatedPost : post)
);
queryClient.setQueryData(
["posts"],
(prev) => prev.map(post => post.id === updatedPost.id ? updatedPost : post)
);
posts contains an array, so you have to find the entry that was updated in the array
correct-apricot
correct-apricotOP•3y ago
Working perfectly 👌 Thank you very much!!!

Did you find this page helpful?