javascript - Redux RTK Query: Listeden yalnızca tek bir elemanı geçersiz kılma
RTK sorgusu için aşağıdaki API'yi tanımladım:
export const postsApi = createApi({
reducerPath: "postsApi",
baseQuery: fetchBaseQuery({ baseUrl: 'https://myservice.co/api/v2/' }),
tagTypes: ["Posts"],
endpoints: (builder) => ({
getAllPosts: builder.query({
query: () => ({ method: "GET", url: "/posts" }),
transformResponse: (response) => response.posts,
providesTags: (result) =>
result
? [
...result.map(({ id }) => ({ type: "Posts", id })),
{ type: "Posts", id: "LIST" },
]
: [{ type: "Posts", id: "LIST" }],
}),
updatePost: builder.mutation({
query: ({ postId, ...body }) => ({
url: `/posts/${postId}`,
method: "POST",
config: { body },
}),
invalidatesTags: (_, __, arg) => [{ type: "Posts", id: arg.id }],
}),
getPost: builder.query({
query: (postId) => ({
method: "GET",
url: `/posts/${postId}`,
}),
providesTags: (_, __, id) => [{ type: "Posts", id }],
}),
}),
});
export const { useGetAllPostsQuery, useUpdatePostMutation, useGetPostQuery } = postsApi;
Bunun yapmasını istediğim şey, updatePost başarılı bir şekilde çağrıldığında, yalnızca tek bir gönderi için önbelleği geçersiz kılması ve bilgileri yeniden almak için getAllPosts yerine getPost sorgusunu kullanmasıdır. Bu herhangi bir şekilde mümkün mü? Gönderiler, getAllPosts sorgusuyla alınan bir tabloda gösteriliyor.
Cevap #1
Hayır. RTK-Query bir belge önbelleğidir (tam yanıt=belge), normalleştirilmiş bir önbellek değildir. Önbelleğe alınmış yanıtların içeriği ve yapısı hakkında hiçbir şey bilmez ve orada hiçbir şeyi kendi başına "birleştirmeye" çalışmaz.
Bunu iyimser bir güncelleme ile manuel olarak yapabilirsiniz, ancak RTK-Q'nun otomatik olarak yaptığı her şey yeniden getirmedir, ki bu çoğu kullanım durumunda fazlasıyla yeterli olmalıdır.
Cevap #2
Bu durumu, updatePost uç noktasında önleyici veya iyimser bir şekilde önbelleği manuel olarak güncelleyerek yönetebilirsiniz.
Mevcut bir önbellek girişini güncellemek için rtk api'de updateQueryData metodunu kullanacağız
Kötümser bir şekilde, mutasyonunuzun sonucu olarak gönderinin yeni sürümünü döndürmelisiniz. Daha sonra liste önbelleğini, güncellenecek gönderiyi listede bularak güncellersiniz :
updatePost: builder.mutation({
query: ({ postId, ...body }) => ({
url: `/posts/${postId}`,
method: "POST",
config: { body },
}),
invalidatesTags: (_, __, arg) => [{ type: "Posts", id: arg.id }],
async onQueryStarted({...patch},{dispatch, queryFulfilled}) {
//here you can do optimistic update using the patch values
//or you can wait for the mutation result
const {data: updatedPost} = await queryFulfilled;
const patchResult = dispatch(
postApi.util.updateQueryData('getAllPosts',undefined,(draft)=>{
const cachedPost = draft.find(p => p.id === updatedPost.id);
if (t) {
Object.assign(cachedPost, updatedPost);
}
})
);
}
}),