React+JavaScript构建Pokedex:单选框筛选与搜索栏问题求助
Pokedex 开发问题解决方案
问题1:世代单选框与apiGeneration字段关联
你的单选框值是"1G"、"2G"这类格式,而API返回的apiGeneration是数字类型(比如1、2),只需在筛选逻辑里做格式转换即可关联:
- 在
filter函数中,若有选中的单选框,提取其值的数字部分(比如"1G"取1),和pokemon.apiGeneration对比; - 未选中时直接返回
true,显示全部宝可梦。
问题2:搜索栏实现(替代DOM事件监听)
React中推荐用受控组件实现输入交互,无需手动添加addEventListener:
- 新增
searchTerm状态存储搜索内容; - 给搜索框绑定
value和onChange,实时更新状态; - 在筛选逻辑里匹配宝可梦名称与搜索关键词。
修改后的完整代码
import axios from "axios"; import React, { useEffect, useState } from "react"; import Card from "./Card"; const Pokedex = () => { const [data, setData] = useState([]); const radios = ["1G", "2G", "3G", "4G", "5G", "6G", "7G", "8G"]; const [selectedRadio, setSelectedRadio] = useState(""); // 新增搜索状态 const [searchTerm, setSearchTerm] = useState(""); useEffect(() => { axios .get("https://pokebuildapi.fr/api/v1/pokemon") .then((res) => setData(res.data)); }, []); return ( <div className="pokemons"> <h2 id="search-title">Pokedex</h2> <p className="search-text">Recherhe par nom</p> <div> {/* 受控搜索框 */} <input type="search" id="search-bar" value={searchTerm} onChange={(e) => setSearchTerm(e.target.value.toLowerCase())} placeholder="输入宝可梦名称..." /> </div> <div className="gen-search"> {radios.map((generation) => ( // 用generation作为唯一key,替代index <ul className="radio-container" key={generation}> <li> <input type="radio" id={generation} name="generationRadio" checked={generation === selectedRadio} onChange={(e) => setSelectedRadio(e.target.id)} /> <label htmlFor={generation}>{generation}</label> </li> </ul> ))} </div> {selectedRadio && ( <button onClick={() => setSelectedRadio("")}> Annuler la recherche </button> )} <div className="pokemon-container"> <ul> {data .filter((pokemon) => { // 世代筛选逻辑 const matchesGeneration = selectedRadio ? pokemon.apiGeneration === Number(selectedRadio[0]) : true; // 名称搜索逻辑(不区分大小写) const matchesSearch = pokemon.name.toLowerCase().includes(searchTerm); // 同时满足两个筛选条件 return matchesGeneration && matchesSearch; }) .map((pokemon) => ( // 用pokemon.id作为key,比index更稳定 <Card key={pokemon.id} pokemon={pokemon} /> ))} </ul> </div> </div> ); }; export default Pokedex;
关键优化说明
- 世代匹配:通过
selectedRadio[0]提取数字部分,转成数字后与apiGeneration对比; - 搜索体验:将输入和名称统一转为小写,实现不区分大小写的搜索;
- 组件稳定性:把
map的key从index替换为唯一标识(generation/pokemon.id),避免不必要的组件重渲染。
内容的提问来源于stack exchange,提问作者jouce
相关产品推荐
相关产品推荐

