无法通过下标0访问userprofile对象,但循环遍历可正常取值
我通过React的useEffect调用API获取用户信息,成功拿到包含Language、name等字段的userprofile数据,也能console.log出完整数据。location.state.id是从之前页面传过来的参数,相关代码如下:
useEffect(() => { fetch('https://1xxxxxxx',{ method: 'POST', headers: { 'Content-Type': 'application/json' }, body:JSON.stringify({ Action : "getPrifles", UserID : location.state.id, }) }) .then((res) => res.json()) .then((json) => { setUserProfile(json.User) }) .catch((err) => { console.log(err.message); }); }, []);
但尝试用console.log(userprofile[0].Lname)访问时,会报错:detail.js:86 Uncaught TypeError: Cannot read properties of undefined (reading '0')。奇怪的是用for-in循环遍历却能正常获取值:
for (var key in userprofile) { console.log(key) // 输出0 console.log(userprofile[key].Lname) // 正确输出Paul }
明明userprofile里只有key为0的对象,为什么直接下标访问会报错?
问题原因
初始状态未正确初始化
你大概率没有给userprofile设置初始值,或者初始值设为了undefined/null。组件第一次渲染时,API请求还没完成,userprofile还是初始状态,这时候访问userprofile[0]就会触发报错——因为undefined没有下标属性。而for-in循环在遍历undefined时会直接跳过循环体,不会执行内部代码,所以不会报错;等API请求完成、userprofile被赋值后,循环才能正常拿到数据。数据类型可能是类数组对象(非标准数组)
另外一种可能是API返回的json.User是一个带有数字键的普通对象(比如{0: {Lname: 'Paul'}}),而非真正的数组。这种情况下,虽然for-in能遍历到key,但直接用[0]访问在初始状态为undefined时还是会触发初始渲染的报错。
解决办法
给userprofile设置初始空数组
初始化状态时设为空数组,避免初始渲染时userprofile为undefined:const [userProfile, setUserProfile] = useState([]);使用可选链操作符做安全访问
即使初始值为空数组,直接访问userprofile[0].Lname还是会因为userprofile[0]是undefined而报错,这时候可以用可选链操作符?.做安全访问:console.log(userprofile?.[0]?.Lname);添加条件判断后再访问
在访问前先检查userprofile是否有数据:if (userprofile && userprofile.length > 0) { console.log(userprofile[0].Lname); }
内容的提问来源于stack exchange,提问作者Adam

