React报错:Cannot read properties of undefined (reading 'common')问题求助
React组件渲染问题修复方案
问题根源
- 初始
country设为空对象{},首次渲染时country.name是undefined,直接访问.common必然触发TypeError。 - 首次执行依赖
data的useEffect时,data是空数组,find方法返回undefined,导致country被设为undefined,后续即使数据加载完成,仍可能因找不到匹配国家出现同样问题。 - 接口请求是异步操作,首次渲染时数据还未返回,直接渲染嵌套属性会触发报错。
修复步骤
- 调整初始状态:把
country的初始值从{}改为null,更便于判断数据是否加载完成。 - 添加渲染条件:在渲染国家名称前,先判断
country和country.name是否存在,避免访问undefined的属性。 - 优化数据查找逻辑:处理
find返回undefined的情况,比如找不到匹配国家时设置默认值或保持null。 - 可选优化:直接通过
countryName请求单个国家数据,替代请求全部国家,减少数据传输量并提升加载速度。
修复后完整代码
import React, { useState, useEffect } from 'react'; import { useParams } from 'react-router-dom'; function Country() { const { countryName } = useParams(); const [country, setCountry] = useState(null); // 方案1:请求单个国家(推荐) useEffect(() => { const formattedName = countryName.replaceAll("-", " "); fetch(`https://restcountries.com/v3.1/name/${formattedName}?fullText=true`) .then(resp => resp.json()) .then(data => { // 处理接口返回数组的情况,取第一个匹配项 setCountry(data[0] || null); }) .catch(err => { console.error('获取国家数据失败:', err); setCountry(null); }); }, [countryName]); // 方案2:保留原请求全部国家的逻辑(注释掉方案1即可启用) // const [data, setData] = useState([]); // useEffect(() => { // fetch('https://restcountries.com/v3.1/all') // .then(resp => resp.json()) // .then(datas => setData(datas)); // }, []) // useEffect(() => { // const formattedName = countryName.replaceAll("-", " "); // const matchedCountry = data.find(a => a.name.common.toLowerCase() === formattedName.toLowerCase()); // setCountry(matchedCountry || null); // }, [data, countryName]) return ( <> {country?.name?.common ? ( <h1>{country.name.common}</h1> ) : ( <h1>未找到对应国家</h1> )} </> ) } export default Country
关键说明
- 使用可选链操作符
?.(React 16.8+支持),可以安全访问嵌套属性,避免TypeError。 - 方案1直接请求单个国家,相比请求全部国家更高效,也减少了前端数据处理的复杂度。
- 增加错误捕获,处理接口请求失败的情况,避免组件崩溃。
内容的提问来源于stack exchange,提问作者Lshiroc
相关产品推荐
相关产品推荐

