Redux Toolkit 查询 (RTKQ) 端点失效和重新验证多次触发

问题描述 投票:0回答:1

作为序言,我查看了 Redux-Toolkit 文档,但没有通过 注入端点 代码分割 找到此问题的答案。我不知道这是否是一个错误,但也会在 RTK 的 Github 上发布。

问题:当您使用 RTK 突变并具有多个

injectEndpoints
时,会多次触发 GET(查询)的重新验证。我有多个injectEndpoints,因为我想分离每个端点。我看到的是对于每个带有
injectEndpoint
的单独文件,RTK 正在为每个文件获取额外的内容。

预期:当您触发 RTK 突变时,任何 GET(查询)的重新验证都应该只触发 1 次,无论 API 中有多少个

injectEndpoints
。这是 RTK 首次引入时的行为。

代码: store.js

import { configureStore } from '@reduxjs/toolkit'

// API
import { baseQuery } from 'api/baseQuery'
import { commentsApi } from 'api/commentsApi'
import { postApi } from 'api/postApi'

const reducer = {
  [baseQuery.reducerPath]: baseQuery.reducer,
  [commentsApi.reducerPath]: commentsApi.reducer,
  [postApi.reducerPath]: postApi.reducer
}

const middleware = getDefaultMiddleware =>
  getDefaultMiddleware()
  .concat(baseQuery.middleware)
  .concat(commentsApi.middleware)
  .concat(postApi.middleware)

export const store = configureStore({
  middleware,
  reducer
})

baseQuery.js

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'

export const baseQuery = createApi({
  baseQuery: fetchBaseQuery({
    baseUrl: 'https://jsonplaceholder.typicode.com',
    prepareHeaders: headers => {
      headers.set('Accept', 'application/json')
      return headers
    }
  }),
  endpoints: () => ({}),
  reducerPath: 'api',
  tagTypes: [
    'comments',
    'posts'
  ]
})

postApi.js

import { baseQuery } from './baseQuery'

export const postApi = baseQuery.injectEndpoints({
  endpoints: ({ mutation, query }) => ({
    addPost: mutation({
      invalidatesTags: ['posts'],
      query: ({ id }) => ({
        method: 'POST',
        url: `/posts`
      })
    }),
    getPosts: query({
      providesTags: ['posts'],
      query: () => `/posts`
    }),
  })
})

export const {
  useAddPostMutation,
  useGetPostsQuery
} = postApi

commentsApi.js

import { baseQuery } from './baseQuery'

export const commentsApi = baseQuery.injectEndpoints({
  endpoints: ({ mutation, query }) => ({
    getComments: query({
      providesTags: ['comments'],
      query: () => `/posts/1/comments`
    }),
  })
})

export const {
  useGetCommentsQuery
} = commentsApi

应用程序.js

import { Button, Stack, Typography } from '@mui/material'
import ChevronLeftRoundedIcon from '@mui/icons-material/ChevronLeftRounded'
import { useAddPostMutation, useGetPostsQuery } from 'api/postApi'
import { useGetCommentsQuery } from 'api/commentsApi'

const App = () => {
  const { data = [] } = useGetPostsQuery()
  const { data: comments = []} = useGetCommentsQuery()
  const [addPost] = useAddPostMutation()

  console.log('comments', comments)

  return (
    <>
      <Button
        onClick={addPost}
        startIcon={<ChevronLeftRoundedIcon />}
      >
        Add Post
      </Button>
      <Stack
        spacing={3}
        sx={{
          alignItems: 'center',
          justifyContent: 'center',
          px: 3
        }}
      >
        <Typography>
          List of Posts
        </Typography>
        {data.map(({ id, title }) => (
          <Typography key={id} variant='body2'>
            {title}
          </Typography>
        ))}
      </Stack>
    </>
  )
}

export default App

index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { Provider } from 'react-redux'
import { store } from 'store/store';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <Provider store={store}>
    <App />
  </Provider>
);

这里唯一的依赖项是 Redux、Redux-Toolkit、Material-UI、Ramda。我在这里使用

jsonplaceholder API
作为一个简单的示例,以便您可以轻松地复制此问题。

发生了什么事

  1. 当您查看网络选项卡时,您将获得
    GET
    posts
    端点的初始
    comments
  2. 点击“添加帖子”按钮
  3. POST
    发射到
    posts
    端点
  4. 网络选项卡向
    GET
    端点触发 3 次
    1 201 
  5. posts
  6. 3 200s 
  7. POST
  8. ,如果没有注入
    GET
    端点,这将返回 2 200s
    comments
    。这意味着对于每个注入的端点,都会发生额外的
    GET
    发生
    
    
  9. 注意: 我没有严格模式下的反应应用程序,因为这不会对最终结果产生任何影响。看起来好像每个
GET

都在重新渲染 App.js 组件,但 Redux Store 不应该导致此问题。在以前使用 Redux 和 RTK 的应用程序中,您可以轻松地像这样编写应用程序,并且永远不会看到为您使用的每个 Mutation 触发多个

GET
问题图片:

    单击按钮之前
  • 点击按钮后
javascript reactjs react-redux redux-toolkit rtk-query
1个回答
0
投票

我几乎可以肯定您的问题是由于添加了有效的“重复”API 切片而引起的,每个

GET

commentsApi
“扩展/增强”了基础
postApi
API 切片。您只需为每个基本查询添加一个 API 切片。无论您导入以在商店中使用什么 API 切片,都应该已经将拆分的 API 切片注入其中。
示例:

baseQuery.js

baseQuery

postApi.js:导入
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'; export const baseQuery = createApi({ baseQuery: fetchBaseQuery({ baseUrl: 'https://jsonplaceholder.typicode.com', prepareHeaders: headers => { headers.set('Accept', 'application/json'); return headers; } }), endpoints: () => ({}), reducerPath: 'api', tagTypes: [ 'comments', 'posts' ] });

API 切片,并导出增强版本。

baseQuery

commentsApi.js:应从 postsApi.js 导入增强型 API 切片,并导出另一个增强型 API 切片版本。

import { baseQuery } from './baseQuery'; const enhancedBaseQuery = baseQuery.injectEndpoints({ endpoints: ({ mutation, query }) => ({ addPost: mutation({ invalidatesTags: ['posts'], query: ({ id }) => ({ method: 'POST', url: `/posts` }) }), getPosts: query({ providesTags: ['posts'], query: () => `/posts` }), }) }) export const { useAddPostMutation, useGetPostsQuery } = enhancedBaseQuery; export default enhancedBaseQuery;

import baseQuery from 'api/postApi';

const enhancedBaseQuery = baseQuery.injectEndpoints({
  endpoints: ({ mutation, query }) => ({
    getComments: query({
      providesTags: ['comments'],
      query: () => `/posts/1/comments`
    }),
  })
});

export const {
  useGetCommentsQuery
} = BaseQuery;

export default BaseQuery;
© www.soinside.com 2019 - 2024. All rights reserved.