React中API请求出现Uncaught (in promise) TypeError: pr is undefined错误
问题分析与修复方案
错误原因拆解
pr is undefined错误
当getINFOPlayerRank.find(rank => name.id === rank.id)找不到与当前玩家ID匹配的排名数据时,会返回undefined,后续访问pr.position和pr.score就会触发类型错误。修改后排名数据重复第一行
改成const pr = getINFOPlayerRank.find(name => name.id === name.id)后,回调函数的参数名name和外层map的参数name重名,导致条件变成当前遍历的排名项ID等于自身ID,这个条件永远为true,所以find总是返回排名数组的第一个元素,所有玩家都显示第一行的排名数据。
修复步骤
1. 修正匹配逻辑,避免参数名冲突
把find的回调参数名改成rank(或其他不冲突的名称),保持原有的ID匹配逻辑:
const pr = getINFOPlayerRank.find(rank => name.id === rank.id)
2. 处理pr为undefined的情况
在返回对象时,给排名相关字段设置默认值,避免报错:
return { id: name.id, name: name.name, status: name.status, position: pr?.position ?? '无排名', score: pr?.score ?? 0 }
这里用了可选链操作符?.和空值合并运算符??,确保即使pr是undefined也不会报错。
3. 修复React组件的其他小问题
- React中元素的类名要用
className代替class - 列表项的
key要用唯一标识符(比如name.id),不能直接用整个对象
修改后的完整代码
import axios from "axios"; import React, { useState, useEffect } from "react"; const News = () => { const [playerName, setPlayerName] = useState([]); const [playerRank, setPlayerRank] = useState([]); const [player, setPlayer] = useState([]); const fetchData = () => { const playerAPI = 'http://localhost:3008/api/players'; const playerRankAPI = 'http://localhost:3008/api/highscore/players'; const getINFOPlayer = axios.get(playerAPI) const getPlayerRank = axios.get(playerRankAPI) axios.all([getINFOPlayer, getPlayerRank]).then( axios.spread((...allData) => { const allDataPlayer = allData[0].data.players const getINFOPlayerRank = allData[1].data.players const newPlayer = allDataPlayer.map(name => { // 修正find参数名,保持正确匹配逻辑 const pr = getINFOPlayerRank.find(rank => name.id === rank.id) return { id: name.id, name: name.name, status: name.status, // 处理pr为undefined的情况,设置默认值 position: pr?.position ?? '无排名', score: pr?.score ?? 0 } }) setPlayerName(allDataPlayer) setPlayerRank(getINFOPlayerRank) console.log(newPlayer) setPlayer(newPlayer) }) ) } useEffect(() => { fetchData() }, []) return ( // 把class改成className <table className="table table-bordered"> <tr> <th>Rank</th> <th>Name</th> <th>Points</th> <th>ID</th> <th>Status</th> </tr> <tbody> {player?.map((playerItem) => { return ( // 用playerItem.id作为唯一key <tr key={playerItem.id}> <td>{playerItem.position}</td> <td>{playerItem.name}</td> <td>{playerItem.score}</td> <td>{playerItem.id}</td> <td>{playerItem.status}</td> </tr> ) })} </tbody> </table> ) } export default News
额外优化建议
- 把
playerRank变量名改成playerRankAPI,避免和状态变量playerRank重名,增强代码可读性 - 调整表头顺序,和表格内容对应,避免混淆
内容的提问来源于stack exchange,提问作者yandry santana
相关产品推荐
相关产品推荐

