如何使用 RTK 查询在单个查询中实现多个 api 调用

How to implement multiple api call in a single query with RTK query

我是 RTK 查询的新手,我正在努力解决我必须实施的用例。

场景: 我必须合并两个 API 调用的结果:第一个 API 调用是私人 API 调用,而第二个是 public API 调用。我需要合并这两个 API 的响应并将计算结果写入 RTK 缓存,以便 UI 可以相应地更新。

问题: 我看到一旦 await queryFullfilled 被调用,RTK 查询立即将 API 调用的响应写入其缓存,然后当我进行计算并尝试使用 [= 更新 RTK 缓存时13=] 缓存会再次改变。这意味着 UI 将渲染两次,第一次使用错误的值(一组人),第二次使用正确的值(由 id 和实体组成的 JSON)。

问题: 有没有办法只将 1 次写入 RTK 缓存,这样我就可以得到我需要的计算值?因为发生的事情是,在某些情况下,当我需要 {ids: [...], entities: {}} JSON.

时,我进入了缓存 array
import { createEntityAdapter } from '@reduxjs/toolkit';
import axios from 'axios';

export const personsAdapter = createEntityAdapter();
const permitsInitialState = personsAdapter.getInitialState();

export const apiSlice = myServiceApi.injectEndpoints({
  endpoints: (builder) => ({
    getPersons: builder.query({
      query: () => ({ url: '/persons', method: 'get' }),
      onQueryStarted: async (_, { dispatch, queryFulfilled }) => {
        try {
          // Resolving the private API call
          const { data: persons } = await queryFulfilled;

          // Just a random public API call
          const { data: todos } = await axios('https://jsonplaceholder.typicode.com/todos');

          const enhancedPersons = /** Here the logic that merge the todos and the persons */

          const state = personsAdapter.setAll(permitsInitialState, enhancedPermits);

          dispatch(
            apiSlice.util.updateQueryData('getPersons', _, (draft) => {
              Object.assign(draft, state);
            })
          );
        } catch (e) {
          console.error(e);
        }
      },
    }),
  }),
});

这是queryFn: Performing multiple requests with a single query

的用例之一
import {
  createApi,
  fetchBaseQuery,
  FetchBaseQueryError,
} from '@reduxjs/toolkit/query'
import { Post, User } from './types'

const api = createApi({
  baseQuery: fetchBaseQuery({ baseUrl: '/ ' }),
  endpoints: (build) => ({
    getRandomUserPosts: build.query<Post, void>({
      async queryFn(_arg, _queryApi, _extraOptions, fetchWithBQ) {
        // get a random user
        const randomResult = await fetchWithBQ('users/random')
        if (randomResult.error) throw randomResult.error
        const user = randomResult.data as User
        const result = await fetchWithBQ(`user/${user.id}/posts`)
        return result.data
          ? { data: result.data as Post }
          : { error: result.error as FetchBaseQueryError }
      },
    }),
  }),
})