我在我的 React Redux Web 应用程序中使用 GameSpot API(使用 Vite 设置)。我在我的组件中看到未定义的数据,尽管 Redux DevTools 将每个查询状态显示为满足其中可见的数据。
我在 App.jsx 中设置了 useEffect 来合并来自三个端点的字段,每个端点返回该端点特有的不同数据:
游戏(类型、发行日期)
评论(分数)
发布(平台、发行商、开发者)。
这是我的设置:
App.jsx
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'
import { useDispatch } from 'react-redux'
import { useEffect } from 'react'
import './App.css'
import { setGames } from './features/Games/gamesSlice'
import { useGetGamesQuery, useGetReviewsQuery, useGetReleasesQuery } from './api/gamespotApiSlice'
import { Header } from './features/Header/Header'
import { GamesList } from './features/Games/GamesList/GamesList'
import { GameDetails } from './features/Games/GameDetails/GameDetails'
function App () {
const dispatch = useDispatch();
const { data: gamesData } = useGetGamesQuery();
const { data: reviewsData } = useGetReviewsQuery();
const { data: releasesData } = useGetReleasesQuery();
useEffect(() => {
if (gamesData && reviewsData && releasesData) {
const mergedData = gamesData.results.map(game => {
const review = reviewsData.results.find(review => review.game.id === game.id);
const release = releasesData.results.find(release => release.game_api_url.includes(game.name));
const publisher = release && release.publishers.length > 0 ? release.publishers[0] : "Unknown";
const developer = release && release.developers.length > 0 ? release.developers[0] : "Unknown";
return {
...game,
id: game.id,
name: game.name,
cover: game.image,
platform: release ? release.platform : null,
genres: game.genres || [],
release_year: new Date(release ? release.release_date : null).getFullYear(),
score: review ? review.score : null,
publisher,
developer
};
});
const sortedGames = [...mergedData].sort((a, b) => b.score - a.score);
dispatch(setGames(sortedGames));
}
}, [dispatch, gamesData, reviewsData, releasesData]);
return (
<Router>
<Header />
<main>
<section className='game-view'>
<Routes>
<Route path='/games/:id' element={<GameDetails />} />
<Route path='/' element={<GamesList />} />
</Routes>
</section>
</main>
</Router>
);
}
export default App;
gamespotApiSlice.js
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
const API_KEY = '?api_key='+ import.meta.VITE_GAMESPOT_API_KEY;
const jsonFormat = '&format=json';
export const gamespotApi = createApi({
reducerPath: 'gamespotApi',
baseQuery: fetchBaseQuery({ baseUrl: '/api' }),
endpoints: (builder) => ({
getGames: builder.query({
query: () => `games/${API_KEY}${jsonFormat}`,
}),
getReviews: builder.query({
query: () => `reviews/${API_KEY}${jsonFormat}&sort=score:desc`,
}),
getReleases: builder.query({
query: () => `releases/${API_KEY}${jsonFormat}`,
})
})
})
export const {
useGetGamesQuery,
useGetReviewsQuery,
useGetReleasesQuery
} = gamespotApi;
export default gamespotApi.reducer;
我还尝试了更简单的方法(例如,直接在 useEffect 中显示 setGames,而不在端点查询中合并和过滤字段),但我仍然在组件中看到 undefined 。任何有关跨端点处理此数据或对未定义数据进行故障排除的建议将不胜感激!
您在此处看到的“未定义”是传递给端点的未定义查询参数。这些是缓存键,是传递的查询参数和端点名称的字符串化组合。
serializeQueryArgs
:
默认情况下,该函数将接受查询参数,对对象进行排序 键(如果适用),将结果字符串化,并将其与 端点名称。这将根据组合创建一个缓存键 参数 + 端点名称(忽略对象键顺序),这样 使用相同参数调用任何给定端点将导致 相同的缓存密钥。
您的端点都不接受任何参数:
endpoints: (builder) => ({
getGames: builder.query({
// No query arg
query: () => `games/${API_KEY}${jsonFormat}`,
}),
getReviews: builder.query({
// No query arg
query: () => `reviews/${API_KEY}${jsonFormat}&sort=score:desc`,
}),
getReleases: builder.query({
// No query arg
query: () => `releases/${API_KEY}${jsonFormat}`,
})
})
在调用查询挂钩的 UI 中,不传递任何参数:
const { data: gamesData } = useGetGamesQuery(); // No query arg
const { data: reviewsData } = useGetReviewsQuery(); // No query arg
const { data: releasesData } = useGetReleasesQuery(); // No query arg
根据提供的代码和用法,您在 Redux-Devtools 中看到的内容似乎是准确且正确的。
例如,如果您有一个接受参数的端点:
getGame: builder.query({
query: (gameId) => `games/${gameId}/${API_KEY}${jsonFormat}`,
})
const { data } = useGetGameQuery("1337");
然后你会在 Redux-Devtools 中看到一个缓存条目键,它可能看起来像
"getGame(1337)"
。