javascript - Redux RTK Query: Membatalkan hanya satu elemen dari senarai
Saya mempunyai API berikut yang ditakrifkan untuk pertanyaan RTK:
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;
Apa yang saya ingin lakukan adalah apabila updatePost dipanggil dengan berjaya, ia hanya akan membatalkan cache untuk satu pos sahaja dan menggunakan query getPost untuk mendapatkan semula maklumat itu dan bukannya getAllPosts. Adakah ini mungkin dilakukan? Pos-pos tersebut dipaparkan dalam satu jadual yang diambil menggunakan query getAllPosts.
Jawapan #1
Tidak. RTK-Query adalah cache dokumen (respon penuh=dokumen), bukan cache yang dinormalisasi. Ia tidak mengetahui apa-apa tentang kandungan respon yang di-cache dan strukturnya - dan ia tidak akan cuba untuk 'menyambung' apa-apa di dalamnya dengan sendirinya.
Anda boleh melakukan itu secara manual dengan kemas kini optimistik, tetapi segala yang dilakukan RTK-Q secara automatik adalah pengambilan semula, yang sepatutnya lebih daripada cukup dalam kebanyakan kes penggunaan.
Jawapan #2
Anda boleh mengendalikan kes ini dengan mengemas kini cache secara manual sama ada secara pesimis atau optimis dalam endpoint updatePost.
Kami akan menggunakan kaedah updateQueryData dalam API rtk untuk mengemas kini entri cache yang sudah wujud
Kerana secara pesimis, anda mesti memulangkan versi baru pos tersebut sebagai hasil mutasi anda. Kemudian anda mengemas kini cache senarai dengan mencari pos untuk dikemas kini dalam senarai itu :
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);
}
})
);
}
}),