-
Hi, I'm new to react query and I'm using react query to fetch a list of posts and then displaying these posts. Each post can be liked by clicking on a button which triggers a mutation. Now in order to update the UI with the new number of likes I can call Here is what I'm currently doing: import { useMutation, useQuery } from '@tanstack/react-query';
import ky from 'ky';
interface PostProps {
post: { id: string; text: string, likes: number };
onLike: () => void;
}
const Post: React.FC<PostProps> = ({ post: { text, likes }, onLike }) => {
return (
<div>
<div>{text}</div>
<div>{likes}</div>
<button
type="button"
onClick={() => {
onLike();
}}
>
Like
</button>
</div>
);
};
const Posts: React.FC = () => {
const { data, status } = useQuery({
queryKey: ['posts'],
queryFn: async () => {
return ky
.get('/api/posts')
.json<{ id: string; text: string; likes: number }[]>();
},
});
const likeMutation = useMutation({
mutationFn: (id: string) => {
return ky.post(`/api/posts/${id}/like`).json();
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['posts'] });
}
});
if (status === 'loading') {
return <div>Loading...</div>;
}
if (status === 'error') {
return <div>Error</div>;
}
return (
<div>
{data.map((post) => {
return (
<Post
key={post.id}
post={post}
onLike={() => {
likeMutation.mutate(post.id);
}}
/>
);
})}
</div>
);
}; |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 3 replies
-
your query always fetches from If you don't want that, have a look at Updates from Mutation Responses. If your mutation returns the updated item, you can write it back to the list in
|
Beta Was this translation helpful? Give feedback.
-
Hi! We can fetch the whole list once, and than instead of creating a single query for the list as a whole, we can create an array of queries for each individual item, to be used with function usePostsQueries() {
const { data } = useQuery({
queryKey: ['posts'],
queryFn: async () => ky.get('/api/posts').json()
})
const results = useQueries(
(data || []).map(post => ({
queryKey: ['posts', post.id],
queryFn: async () => post
}))
)
const resultsData = results.map(res => res.data)
return useQuery({
queryKey: ['posts', ...resultsData],
queryFn: async () => resultsData
})
} By this approach, the list query hook is the one to assure it is up to date. Single item mutations can just invalidate using the key |
Beta Was this translation helpful? Give feedback.
your query always fetches from
/api/posts
, so an invalidation will always refetch the entire list. That's often a good thing - items could have been added or altered by someone else in the meantime, so now you'd have the up-to-date data.If you don't want that, have a look at Updates from Mutation Responses. If your mutation returns the updated item, you can write it back to the list in
onSuccess
: