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

如何基于Pokemon API实现搜索功能?现有React代码调整求助

问题排查与修复方案

你当前代码存在两个核心问题,按需求调整后即可实现搜索功能:

  1. 状态依赖不匹配:你用于接收搜索词的状态是filter,但触发数据拉取的useEffect依赖项为无关的option,搜索词变更后不会触发任何逻辑更新,自然没有效果。
  2. 未实现过滤逻辑:你已经在本地存储了拉取到的全量宝可梦数据,无需额外编写过滤请求逻辑,直接做前端过滤即可,不需要重复调用接口。

具体修改代码

1. 简化原有请求方法(可选优化)

你封装的getAllPokemon多包了一层不必要的Promise,可直接简化为:

export async function getAllPokemon(url) {
  const res = await fetch(url);
  return res.json();
}

2. 修改App组件逻辑

仅需要在渲染宝可梦列表前增加过滤步骤即可,无需改动原有数据拉取逻辑:

function App() {
  // 原有其他状态保留:pokemonData、loading、option等
  const [filter, setFilter] = useState("");
  const initialURL = `https://pokeapi.co/api/v2/pokemon?limit=50`

  // 原有handleSearchChange、useEffect、loadPokemon逻辑全部保留即可
  const handleSearchChange = (e) => {
    setFilter(e.target.value);
  };

  useEffect(() => {
    async function fetchData() {
      let response = await getAllPokemon(initialURL)
      await loadPokemon(response.results);
      setLoading(false);
    }
    fetchData();
  }, [option]) // 如果你不需要用option切换分页/数量,可把依赖项改为空数组,初始化拉一次数据即可

  const loadPokemon = async (data) => {
    let _pokemonData = await Promise.all(data.map(async pokemon => {
      let pokemonRecord = await getPokemon(pokemon)
      return pokemonRecord
    }))
    setPokemonData(_pokemonData);
  }

  // 新增:基于搜索词过滤宝可梦列表
  const filteredPokemon = pokemonData.filter(pokemon => 
    // 不区分大小写匹配宝可梦名称
    pokemon.name.toLowerCase().includes(filter.trim().toLowerCase())
  )

  return (
    <>
      <div >
        <div>
          <input
            type="text"
            id="header-search"
            placeholder="Search Pokemon"
            name="s"
            onChange={handleSearchChange}
          />
          <button >Search</button>
        </div>
      </div>
      <div>
        {loading ? <h1 style={{ textAlign: 'center' }}>Loading...</h1> : (
          <>        
            <div className="grid-container">
              {/* 把原来的pokemonData.map替换为过滤后的数组 */}
              {filteredPokemon.map((pokemon, index) => {
                return <Card key={index} pokemon={pokemon} />
              })}
            </div>
          </>
        )}
      </div>
    </>
  );
}

export default App;

可选扩展:点击搜索按钮才触发过滤

如果不需要实时搜索,希望点击按钮才生效,可以新增一个搜索状态:

const [searchTerm, setSearchTerm] = useState("")
// 点击按钮时把当前输入的filter赋值给searchTerm
const handleSearch = () => setSearchTerm(filter)

过滤逻辑改为基于searchTerm过滤,同时给搜索按钮绑定onClick={handleSearch}即可。

内容的提问来源于stack exchange,提问作者Vetox88

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 03:06:01