正如标题所说。这对我来说非常奇怪。
我非常清楚地从 categoriesApi.js 调用 getThisCategory(genre) 查询,它应该是:
'https://kitsu.io/api/edge/anime?filter%5Bcategories%5D=${流派}'
但是在我的控制台中有一个错误,上面写着:
"得到 https://kitsu.io/api/edge/Vampire/anime?limit=20 404"。
在我看来,这看起来像来自 animeApi.js 文件的查询,并传入了流派参数。我不知道为什么它调用此查询。
请有人帮忙,这真的很令人沮丧。
以下文件:
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;
流派页面.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]);
店铺.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),
});
应用.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;
有点跑题,但足够重要,可以把它变成一个答案 - 希望其他人将来也能阅读它:
请不要使用这种createRequest
辅助功能。
这是从严重误解baseQuery
用途的教程中获取的。
本质上,baseQuery
已经是一个这样的createRequest
函数 - 端点的query
函数的返回值将作为第一个参数传递到baseQuery
,在fetchBaseQuery
的情况下,它将调用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。如果要将其拆分到多个文件中,可以查看有关代码拆分的文档
想通了——我很愚蠢。
问题出在 App.js 中设置的路线上。
因为 GenrePage 是在路由 '/anime/:genre' 上调用的,而 AnimeCategoryPage 是在 '/anime/:category' 上调用的,所以 react-router 总是调用基础 '/anime' 上的第一个组件,即 AnimeCategoryPage 而不是 GenrePage。
通过将流派页面的路由更改为"/探索/:流派"来修复