如何用Redux Toolkit Query实现全量宝可梦(含身高体重)的端点及前端展示
使用Redux Toolkit Query + React 展示全量宝可梦身高体重数据
一、配置RTK Query API切片
宝可梦官方API分页返回列表,且列表数据不包含身高体重信息,需要先获取全量列表,再批量请求每个宝可梦的详情接口。我们用queryFn自定义请求逻辑实现:
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'; export const pokemonApi = createApi({ reducerPath: 'pokemonApi', baseQuery: fetchBaseQuery({ baseUrl: 'https://pokeapi.co/api/v2/' }), endpoints: (builder) => ({ getAllPokemons: builder.query({ async queryFn(_, queryApi, extraOptions, baseQuery) { // 第一步:获取全量宝可梦列表(limit设为1000覆盖现有所有宝可梦) const listRes = await baseQuery('pokemon?limit=1000'); if (listRes.error) return { error: listRes.error }; // 第二步:并行请求所有宝可梦的详情接口 const detailRequests = listRes.data.results.map(pokemon => baseQuery(pokemon.url)); const detailResponses = await Promise.all(detailRequests); // 第三步:提取需要的字段,过滤请求失败的数据 const validPokemons = detailResponses .filter(res => !res.error) .map(res => ({ id: res.data.id, name: res.data.name, height: res.data.height, weight: res.data.weight, avatar: res.data.sprites.front_default // 可选添加头像增强展示 })); return { data: validPokemons }; }, }), }), }); // 导出自动生成的Hook供组件使用 export const { useGetAllPokemonsQuery } = pokemonApi;
二、注册API切片到Redux Store
将RTK Query的reducer和中间件添加到Redux配置中:
import { configureStore } from '@reduxjs/toolkit'; import { pokemonApi } from './features/pokemon/pokemonApi'; export const store = configureStore({ reducer: { // 注册API切片的reducer [pokemonApi.reducerPath]: pokemonApi.reducer, }, // 添加RTK Query的中间件,处理缓存、失效等逻辑 middleware: getDefaultMiddleware => getDefaultMiddleware().concat(pokemonApi.middleware), });
三、React组件中渲染数据
在组件中使用生成的Hook获取数据,处理加载、错误状态,并渲染列表:
import { useGetAllPokemonsQuery } from './features/pokemon/pokemonApi'; function PokemonList() { const { data, error, isLoading } = useGetAllPokemonsQuery(); // 加载状态 if (isLoading) return <div>正在加载宝可梦数据...</div>; // 错误状态 if (error) return <div>加载失败:{error.toString()}</div>; return ( <div style={{ padding: '20px', maxWidth: '1200px', margin: '0 auto' }}> <h2>全量宝可梦身高体重数据</h2> <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(200px, 1fr))', gap: '20px' }}> {data.map(pokemon => ( <div key={pokemon.id} style={{ border: '1px solid #eee', borderRadius: '8px', padding: '10px', textAlign: 'center' }}> <img src={pokemon.avatar} alt={pokemon.name} style={{ width: '100px', height: '100px' }} /> <h3 style={{ textTransform: 'capitalize' }}>{pokemon.name}</h3> <p>身高:{(pokemon.height / 10).toFixed(1)} m</p> <p>体重:{(pokemon.weight / 10).toFixed(1)} kg</p> </div> ))} </div> </div> ); } export default PokemonList;
四、关键说明
- 单位转换:宝可梦API返回的身高单位是分米,体重是百克,除以10转换成米和千克更直观
- 请求优化:如果担心并行请求触发浏览器并发限制,可以把批量请求改成分批处理(比如每次请求20个)
- 缓存机制:RTK Query会自动缓存请求结果,后续组件挂载不会重复发起请求,如需更新可调用
refetch方法
内容的提问来源于stack exchange,提问作者Omer
相关产品推荐
相关产品推荐

