React报错Cannot read properties of undefined (reading 'map') 详情页传参失败怎么解决
问题解决步骤
核心问题说明
你当前的报错是两个原因导致的:
- 路由渲染
PokemonDetail时没有将App.js中的pokemons数组传递给该组件,导致PokemonDetail中读取props.pokemons为undefined PokemonDetail中没有从路由参数获取对应宝可梦id,直接遍历所有宝可梦的逻辑不符合需求,且abilities为数组直接渲染会抛出类型错误
具体修改方案
1. 修改App.js的路由传参逻辑
将原有的Route标签替换为以下代码,通过render属性将pokemons数组和路由参数一起传递给PokemonDetail组件:
<Route path="/pokemon/:id" render={(routeProps) => <PokemonDetail {...routeProps} pokemons={pokemons} />} />
2. 修改PokemonList.js的跳转路径
将跳转链接改为绝对路径,避免路由嵌套时出现路径拼接错误:
<StyledLink to={`/pokemon/${pokemon.id}`}>
3. 重写PokemonDetail.js的业务逻辑
修改后代码如下,先从路由参数获取id匹配对应宝可梦,再做渲染:
function PokemonDetail(props) { // 路由参数默认是字符串,转为数字和宝可梦id匹配 const pokemonId = Number(props.match.params.id); // 从宝可梦列表中筛选对应id的单条数据 const targetPokemon = props.pokemons.find(pokemon => pokemon.id === pokemonId); // 加加载态避免数据未加载完成时渲染报错 if (!targetPokemon) return <div>数据加载中,请稍候</div>; return ( <div className="col-md-3 my-5"> <div className="card-outer w-100 p-2 rounded text-center"> <h5 className="card-header"> 技能:{targetPokemon.abilities.map(item => item.ability.name).join('、')} </h5> <img src={targetPokemon.sprites.other.dream_world.front_default} alt={`${targetPokemon.name}的图片`}/> </div> </div> ); }
可选优化(非必须)
你原有的数据请求逻辑用forEach+async会触发多次setPokemons,导致多次重渲染,可以改用Promise.all一次性获取所有数据后再更新状态:
const getPokemonRequest = async () => { const url = `https://pokeapi.co/api/v2/pokemon?offset=5&limit=5`; const response = await fetch(url); const fivePokemons = await response.json(); // 批量生成请求 const pokemonRequests = fivePokemons.results.map(pokemon => fetch(pokemon.url).then(res => res.json())); // 等待所有请求完成后一次性更新状态 const pokemonSpecsList = await Promise.all(pokemonRequests); setPokemons(pokemonSpecsList); };
内容的提问来源于stack exchange,提问作者Yasmins
相关产品推荐
相关产品推荐

