React中如何实现子组件传值到父组件并按下拉框选中值过滤渲染
方案选择说明
你当前的项目场景下,前端本地筛选的方案更简便易实现,而且单页仅加载9条数据的情况下,前端筛选的性能完全够用,是非常合理的方案。你不需要通过子组件回调回传类型数据,这个思路是绕远路了,给你两种几乎不用改现有逻辑的实现方式:
最简实现方式(无需调整现有请求逻辑)
直接把父组件拿到的选中类型作为props传给卡片组件,卡片内部判断类型不匹配时直接返回空即可,总修改量不到10行:
- 修改
PokemonList组件中渲染卡片的代码,传入选中的类型:
{result.results.map((pokemon) => ( <PokemonCard key={pokemon.name} pokemon={pokemon} selectedType={type} /> ))}
- 修改
PokemonCard组件,拿到类型后做渲染判断:
// 原代码中拿到types的部分后新增判断 const { types, abilities } = data; // 没有选中类型/选中全部时正常渲染,否则只渲染匹配类型的卡片 if (selectedType !== 'All' && selectedType && types[0].type.name !== selectedType) { return null; }
更规范的实现方式(避免空占位)
如果不想出现筛选后页面有空白占位的问题,可以把宝可梦详情的请求上移到PokemonList组件,在父组件完成筛选后再渲染卡片:
- 在
PokemonList中拿到基础列表后,并行请求所有宝可梦的详情数据,筛选出匹配类型的条目再渲染:
// 新增useState存储宝可梦详情列表 const [pokemonDetails, setPokemonDetails] = useState([]); // 监听基础列表变化,请求详情 useEffect(() => { const fetchDetails = async () => { const details = await Promise.all( result.results.map(p => fetch(`https://pokeapi.co/api/v2/pokemon/${p.name}`).then(res => res.json())) ); setPokemonDetails(details); }; fetchDetails(); }, [result]); // 渲染前先筛选 const filteredPokemon = type === 'All' || !type ? pokemonDetails : pokemonDetails.filter(p => p.types[0].type.name === type);
- 渲染时直接遍历筛选后的列表,
PokemonCard直接接收详情数据即可,不需要再单独发请求。
关于服务端筛选的补充
如果后续你要做全量宝可梦的筛选,再考虑用服务端筛选方案:直接调用对应type的接口,就能拿到该类型下的所有宝可梦列表,再做分页渲染即可,当前小数据量场景完全没必要用这个方案。
内容的提问来源于stack exchange,提问作者hawe
相关产品推荐
相关产品推荐

