You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何结合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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 05:15:40