Redux Toolkit Query: 从“mutation”响应中减少状态

5
假设我有一个 RESTish API 来管理“帖子”。
  • GET /posts 返回所有帖子。
  • PATCH /posts:id 更新某个帖子并响应新记录数据。
我可以通过 RTK query 实现这个功能,例如:
const TAG_TYPE = 'POST';

// Define a service using a base URL and expected endpoints
export const postsApi = createApi({
  reducerPath: 'postsApi',
  tagTypes: [TAG_TYPE],
  baseQuery,
  endpoints: (builder) => ({
    getPosts: builder.query<Form[], string>({
      query: () => `/posts`,
      providesTags: (result) =>
        [
          { type: TAG_TYPE, id: 'LIST' },
        ],
    }),
    updatePost: builder.mutation<any, { formId: string; formData: any }>({
      // note: an optional `queryFn` may be used in place of `query`
      query: (data) => ({
        url: `/post/${data.formId}`,
        method: 'PATCH',
        body: data.formData,
      }),
      // this causes a full re-query.  
      // Would be more efficient to update state based on resp.body
      invalidatesTags: [{ type: TAG_TYPE, id: 'LIST' }],
    }),
  }),
});

updatePost运行时,它会使LIST标签失效,导致getPosts再次运行。
然而,由于PATCH操作响应本身就是新数据,我想避免发出额外的服务器请求,而只需使用response.body的内容更新特定记录的reducer状态。
这似乎是一个常见的用例,但我无法找到任何关于如何执行此类操作的文档。
1个回答

6
你可以稍晚些时间应用在 乐观更新 中描述的机制:
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query'
import { Post } from './types'

const api = createApi({
  // ...
  endpoints: (build) => ({
    // ...
    updatePost: build.mutation<void, Pick<Post, 'id'> & Partial<Post>>({
      query: ({ id, ...patch }) => ({
        // ...
      }),
      async onQueryStarted({ id, ...patch }, { dispatch, queryFulfilled }) {
        const { data } = await queryFulfilled
        dispatch(
          api.util.updateQueryData('getPost', id, (draft) => {
            Object.assign(draft, data)
          })
        )
      },
    }),
  }),
})

啊,那很有道理。我想是onQueryStarted让我走偏了。谢谢! - NSjonas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接