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);
                           }
                      })
                    );
                  
              }
         }),