جافاسكريبت - Redux RTK Query: إبطال عنصر واحد فقط من القائمة
لدي واجهة برمجة التطبيقات التالية معرفة لاستعلام 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;
ما أود أن يحدث هو أنه عندما يتم استدعاء updatePost بنجاح، فإنه يقوم فقط بإبطال الكاش لمنشور واحد واستخدام استعلام getPost لإعادة جلب المعلومات بدلاً من getAllPosts. هل هذا ممكن بأي طريقة؟ المنشورات معروضة في جدول تم جلبه باستخدام استعلام getAllPosts.
الإجابة رقم 1
لا. RTK-Query هو ذاكرة مؤقتة للمستندات (الاستجابة الكاملة=مستند)، وليس ذاكرة مؤقتة مُطَبَّعَة. إنه لا يعرف شيئًا عن محتويات الاستجابات المخزنة وبنيتها - ولن يحاول أبدًا "تجميع" أي شيء هناك بنفسه.
يمكنك القيام بذلك يدويًا باستخدام تحديث متفائل، لكن كل ما يفعله RTK-Q تلقائيًا هو إعادة الجلب، وهو ما يجب أن يكون كافيًا في معظم حالات الاستخدام.
الإجابة رقم 2
يمكنك التعامل مع هذه الحالة عن طريق تحديث التخزين المؤقت يدوياً إما بطريقة متشائمة أو متفائلة في نقطة نهاية updatePost.
سنستخدم طريقة updateQueryData في واجهة برمجة التطبيقات rtk لتحديث مدخل ذاكرة التخزين المؤقت الموجود بالفعل
للاختياري المتشائم، يجب عليك إعادة النسخة الجديدة من المنشور كنتيجة لتعديلك. ثم تقوم بتحديث ذاكرة التخزين المؤقت للقائمة عن طريق العثور على المنشور الذي سيتم تحديثه في القائمة:
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);
}
})
);
}
}),