redux RTK查询-我明确调用了一个查询,但由于某种原因,正在执行另一个查询

jc3wubiy  于 2022-11-12  发布在  其他
关注(0)|答案(2)|浏览(129)

正如标题所说。这对我来说非常奇怪。
我很清楚地调用了categoriesApi.js中的getThisCategory(genre)查询,它应该是:
'动画过滤器%5B类别%5D =${类型}'
但在我的控制台中出现了一个错误,显示:
“获取https://kitsu.io/api/edge/Vampire/anime?limit=20 404”。
在我看来,这看起来像是animeApi.js文件中的查询,传入了genre参数。我不知道它为什么要调用这个查询。
请能有人帮忙,这真是令人沮丧。
以下文件:
animeApi.js(不应被调用但被调用的查询):

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

const animeApiHeaders = {
    "Accept": "application/vnd.api+json",
    "Content-Type": "application/vnd.api+json",
};

const baseUrl = 'https://kitsu.io/api/edge';

const createRequest = (url) => ({ url, headers: animeApiHeaders });

export const animeApi = createApi({
    reducerPath: 'animeApi',
    baseQuery: fetchBaseQuery({ baseUrl }),
    endpoints: (builder) => ({
        getCategoryOfAnime: builder.query({
            query: (category) =>
                createRequest(`/${category}/anime?limit=20`)
        }),
    })
});

export const { useGetCategoryOfAnimeQuery } = animeApi;

categoriesApi.js(应该被调用的查询):

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

const categoryHeaders = {
    "Accept": "application/vnd.api+json",
    "Content-Type": "application/vnd.api+json",
};

const baseUrl = 'https://kitsu.io/api/edge';

const createRequest = (url) => ({ url, headers: categoryHeaders });

export const categoriesApi = createApi({
    reducerPath: 'categoriesApi',
    baseQuery: fetchBaseQuery({ baseUrl }),
    endpoints: (builder) => ({
        getAllCategories: builder.query({
            query: () => 
                createRequest(`/categories?page%5Blimit%5D=40`)
        }),
        getThisCategory: builder.query({
            query: (genre) =>
                createRequest(`/anime?filter%5Bcategories%5D=${genre}`)
        }),
    })
});

export const { useGetAllCategoriesQuery, useGetThisCategoryQuery } = categoriesApi;

GenrePage.js(仅组件的相关部分):

import React, { useState, useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { Link, useParams } from 'react-router-dom';
import { useGetThisCategoryQuery } from '../../services/categoriesApi';
import { addThisCategory } from './GenrePageSlice';
import CircularProgress from "@mui/material/CircularProgress";
import './GenrePage.css';
import AnimeCard from '../AnimeCard/AnimeCard';

const GenrePage = () => {

    const { genre } = useParams();
    const dispatch = useDispatch();
    const genreData = useSelector((state) => state.genrePage.thisCategory);
    const { data: thisCategory, isFetching } = useGetThisCategoryQuery(genre);

    useEffect(() => {
        dispatch(addThisCategory(thisCategory));
    }, [thisCategory]);

store.js:

import { combineReducers, configureStore } from "@reduxjs/toolkit";

import { animeApi } from "../services/animeApi";
import { categoriesApi } from "../services/categoriesApi";

import animeBannerReducer from '../components/AnimeBanner/AnimeBannerSlice';
import animeCategoryReducer from "../components/AnimeCategoryPage/AnimeCategoryPageSlice";
import categoriesReducer from '../components/Categories/CategoriesSlice';

export default configureStore({
    reducer: {
        [animeApi.reducerPath]: animeApi.reducer,
        [categoriesApi.reducerPath]: categoriesApi.reducer,
        animeBanner: animeBannerReducer,
        animeCategory: animeCategoryReducer,
        categories: categoriesReducer,
    },
    middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware().concat(animeApi.middleware, categoriesApi.middleware),
});

App.js:

import React, { useState } from 'react';
import { BrowserRouter, Routes, Route, Link } from 'react-router-dom';

import "./App.css"

import Header from '../components/Header/Header';
import Homepage from '../components/Homepage/Homepage';
import AnimeCategoryPage from '../components/AnimeCategoryPage/AnimeCategoryPage';
import GenrePage from '../components/GenrePage/GenrePage';

const App = () => {

  return (
    <BrowserRouter>
        <div className="app">
          <Header />
          <Routes>
            <Route path="/" element={<Homepage />} />
            <Route path="/anime/:category" element={<AnimeCategoryPage />} />
            <Route path="/anime/:genre" element={<GenrePage />} />
          </Routes>
        </div>
    </BrowserRouter>

  );
};

export default App;
8gsdolmq

8gsdolmq1#

虽然有点离题,但它的重要性足以让我把它作为一个答案--希望其他人将来也会读到它:

请不要使用这种createRequest辅助函数。

这是从一个教程,严重误解了什么是baseQuery
本质上,baseQuery已经是一个createRequest函数,如下所示:端点的query函数的返回值将作为第一个参数传递给baseQuery,在fetchBaseQuery的情况下,baseQuery将调用fetch
因此,请在此处正确使用fetchBaseQuery

const baseUrl = 'https://kitsu.io/api/edge';

export const categoriesApi = createApi({
    reducerPath: 'categoriesApi',
    baseQuery: fetchBaseQuery({ 
      baseUrl,
//    either you can just set `headers` here:
//    headers: categoryHeader

//    or you use `prepareHeaders` where you can do some calulations and have access to stuff like `getState` or the endpoint name
      prepareHeaders: (headers, { getState, endpoint, type, forced }) => {
         headers.set("Accept", "application/vnd.api+json")
         headers.set("Content-Type": "application/vnd.api+json")
         return headers
      }
     }),
    endpoints: (builder) => ({
        getAllCategories: builder.query({
          query: () => { url: `/categories?page%5Blimit%5D=40` }
// or the short notation: if you only have an `url` just pass a string
//        query: () => `/categories?page%5Blimit%5D=40`
        }),
    })
});

另外,这也可能是教程中的一个误解:你应该在几乎所有的情况下只有一个api用于你的整个应用程序。如果你想把它分割成多个文件,你可以see the docs on Code Splitting

nsc4cvqm

nsc4cvqm2#

我知道了-我太蠢了。
问题出在我在App.js中设置的路线。
因为类型页面是在路由“/anime/:genre”上调用的,而动画类别页面是在“/anime/:category”上调用的,所以React路由器总是调用基础“/anime”上的第一个组件,即动画类别页面,而不是类型页面。
通过将GenrePage的路径更改为“/explore/:genre”进行修复

相关问题