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

React中如何实现子组件传值到父组件并按下拉框选中值过滤渲染

方案选择说明

你当前的项目场景下,前端本地筛选的方案更简便易实现,而且单页仅加载9条数据的情况下,前端筛选的性能完全够用,是非常合理的方案。你不需要通过子组件回调回传类型数据,这个思路是绕远路了,给你两种几乎不用改现有逻辑的实现方式:

最简实现方式(无需调整现有请求逻辑)

直接把父组件拿到的选中类型作为props传给卡片组件,卡片内部判断类型不匹配时直接返回空即可,总修改量不到10行:

  1. 修改PokemonList组件中渲染卡片的代码,传入选中的类型:
{result.results.map((pokemon) => (
  <PokemonCard key={pokemon.name} pokemon={pokemon} selectedType={type} />
))}
  1. 修改PokemonCard组件,拿到类型后做渲染判断:
// 原代码中拿到types的部分后新增判断
const { types, abilities } = data;
// 没有选中类型/选中全部时正常渲染,否则只渲染匹配类型的卡片
if (selectedType !== 'All' && selectedType && types[0].type.name !== selectedType) {
  return null;
}

更规范的实现方式(避免空占位)

如果不想出现筛选后页面有空白占位的问题,可以把宝可梦详情的请求上移到PokemonList组件,在父组件完成筛选后再渲染卡片:

  1. 在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);
  1. 渲染时直接遍历筛选后的列表,PokemonCard直接接收详情数据即可,不需要再单独发请求。

关于服务端筛选的补充

如果后续你要做全量宝可梦的筛选,再考虑用服务端筛选方案:直接调用对应type的接口,就能拿到该类型下的所有宝可梦列表,再做分页渲染即可,当前小数据量场景完全没必要用这个方案。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 09:54:03