如何结合React Query根据pokeDexNum状态变化获取宝可梦招式?
React Query 结合宝可梦队伍构建器的实现方案
问题场景
开发宝可梦队伍构建器时,需要根据用户选中的宝可梦(通过pokeDexNum状态控制),请求PokeAPI获取对应招式列表并填充到招式下拉框中。原有用useEffect的方式可以实现,但希望借助React Query的缓存功能减少重复请求,同时避免在pokeDexNum为null时发起无效请求。
原尝试的useQuery写法会在pokeDexNum为null时触发请求,不符合需求。
解决方案
1. 用enabled参数控制请求触发时机
React Query的useQuery提供了enabled配置项,只有当该值为true时才会执行查询。我们可以将其与pokeDexNum的存在性绑定,确保仅当用户选中宝可梦(pokeDexNum不为null)时才发起请求:
const { isLoading, error, data } = useQuery( ['getPokeMoves', pokeDexNum], // 数组形式的查询键,确保每个宝可梦的缓存独立 () => fetch(`https://pokeapi.co/api/v2/pokemon/${pokeDexNum}`).then(res => res.json()), { enabled: !!pokeDexNum } // 仅当pokeDexNum存在时启用查询 )
- 查询键说明:使用包含
pokeDexNum的数组作为查询键,React Query会根据数组内的所有值区分缓存条目,不同宝可梦的请求结果会被单独缓存,切换时直接读取缓存无需重复请求。 - enabled逻辑:
!!pokeDexNum会将null/undefined转换为false,非空值转换为true,完美规避无效请求。
2. 转换招式数据为下拉框选项格式
当请求成功返回data后,我们可以从data.moves中提取招式信息,转换成下拉组件需要的{text, value}格式:
const moveOptions = data?.moves.map(move => ({ text: move.move.name.replace('-', ' '), // 替换连字符为空格,优化显示效果 value: move.move.name })) || [];
3. 完整组件示例
将上述逻辑整合到组件中,同时添加加载、错误状态处理和交互优化:
import { useState } from 'react'; import { useQuery } from '@tanstack/react-query'; import { Form } from 'semantic-ui-react'; const PokemonTeamBuilder = () => { const [pokeDexNum, setPokeDexNum] = useState(null); const { isLoading, error, data } = useQuery( ['getPokeMoves', pokeDexNum], () => fetch(`https://pokeapi.co/api/v2/pokemon/${pokeDexNum}`).then(res => res.json()), { enabled: !!pokeDexNum } ); const moveOptions = data?.moves.map(move => ({ text: move.move.name.replace('-', ' '), value: move.move.name })) || []; return ( <Form> <Form.Group> <Form.Dropdown label="Pokemon" search selection clearable selectOnBlur={false} value={pokeDexNum} onChange={(e, data) => setPokeDexNum(data.value)} options={[ { text: "Tepig", value: 498 }, { text: "Oshawott", value: 501 }, { text: "Snivy", value: 495 }, ]} loading={isLoading} /> <Form.Dropdown label="Moves" search selection options={moveOptions} disabled={!pokeDexNum || isLoading} /> </Form.Group> {error && <p style={{ color: 'red' }}>加载招式失败:{error.message}</p>} </Form> ); }; export default PokemonTeamBuilder;
关键优化点
- 选中宝可梦时,宝可梦下拉框显示加载状态,提升用户感知
- 招式下拉框在未选中宝可梦或加载中时禁用,避免无效操作
- 添加错误状态提示,让用户了解请求失败原因
内容的提问来源于stack exchange,提问作者user20669217
相关产品推荐
相关产品推荐

