[英]I am wondering why my useEffect data is empty on first render when I populate it on first render using useEffect
我正在使用 REST 國家/地區 API 創建一個應用程序,我使用 useEffect 掛鈎在第一次渲染上調用 API 並使用我需要的數據填充我的 useState 數組。 當我嘗試在組件的返回語句中訪問此數據時,它讀取為未定義。 我什至嘗試添加一個三元運算符來首先檢查數據是否為空,如果不是 output 它,但它仍然讀取未定義但如果我注釋掉代碼並刷新頁面,數據將被填充,然后可以取消注釋代碼以顯示如果我再次刷新頁面,數據讀取為未定義。 我對為什么會發生這種情況感到非常困惑,因此非常感謝任何幫助。
我的.js文件:
const CountryInfo = () => {
const [data, setData] = useState([{}])
let countryName = window.location.pathname;
countryName = countryName.replace('/', '');
countryName = countryName.split('%20');
countryName = countryName.join(' ');
console.log(countryName)
useEffect(() => {
axios.get(`https://restcountries.com/v3.1/name/${countryName}`).then(response => {
console.log(response);
setData([{
name: countryName,
image: response.data[0].flags.png,
nativeName: response.data[0].name.nativeName.nld,
population: response.data[0].population,
region: response.data[0].region,
subRegion: response.data[0].subregion,
capital: response.data[0].capital[0],
borderCountries: response.data[0].borders,
topLevelDomain: response.data[0].tld[0],
currencies: response.data[0].currencies,
languages: response.data[0].languages,
}])
})
},[])
console.log(data)
return(
<div className='country-info-content'>
<Link to='/' className='info-button'>
<button className='button-info'>BACK</button>
</Link>
<div className='data-info'>
<img src={data[0].image} className='flag-img'/>
<div className='country-name'>
<span className='name'>{data[0].name}</span>
<div className='info-description'>
<div>
<div>
<span>Native Name:</span> {data[0].nativeName.common}
</div>
{/* {data?
<div>
<div>
<span className='title'>Native Name:</span> {data.nativeName.common}
</div>
<div>
<span className='title'>Population:</span> {data.population.toLocaleString(undefined)}
</div>
<div>
<span className='title'>Region:</span> {data.region}
</div>
<div>
<span className='title'>Sub Region:</span> {data.subRegion}
</div>
<div>
<span className='title'>Capital:</span> {data.capital}
</div>
</div>:null} */}
{/* {data ?
<div>
<span>Native Name: </span>{data[0].nativeName.common}
</div>: null
} */}
</div>
<div className='right-info'>
<div>
<span className='title'>Top Level Domain:</span> {data.topLevelDomain}
</div>
<div>
<span className='title'>Currency:</span> {data.topLevelDomain}
</div>
<div>
<span className='title'>Languages:</span> {data.topLevelDomain}
</div>
</div>
</div>
</div>
</div>
</div>
)
}
export default CountryInfo;
useEffect將在您的頁面第一次呈現后觸發,這就是組件第一次呈現時未定義數據的原因。
您需要處理它,並且三元運算符是一種常見做法:
return data ? <div>...</div> : null;
或者
return data ? <div>...</div> : <div>Loading...</div>;
更新:錯誤消息是通過讀取未定義的common
屬性觸發的。 你這樣做的唯一地方是
data[0].nativeName.common
這意味着data[0]
存在,但nativeName
未定義。 nativeName
存儲response.data[0].name.nativeName.nld,
的值。 您應該仔細檢查從 API 返回的數據是否具有預期的格式並且是否設置了response.data[0].name.nativeName.nld
。
UPDATE2 :就像 Zeno 在評論中注意到的那樣, data
的默認值是[{}]
,並且在三元運算符中始終評估為true
。
為什么在獲取數據之前不設置默認undefined
?
還要確保將結果稱為data[0]
,因為這是您存儲響應的位置。 或者通過執行以下操作來簡化您的代碼:
setData({
name: countryName,
image: response.data[0].flags.png,
nativeName: response.data[0].name.nativeName.nld,
population: response.data[0].population,
region: response.data[0].region,
subRegion: response.data[0].subregion,
capital: response.data[0].capital[0],
borderCountries: response.data[0].borders,
topLevelDomain: response.data[0].tld[0],
currencies: response.data[0].currencies,
languages: response.data[0].languages,
})
無需在其中存儲數組。
您有數據映射錯誤。 嘗試在數據數組中設置本機名稱時,您的數據設置不正確。
你有:
setData([
{
...
nativeName: response.data[0].name.nativeName.nld,
...
}
]);
並返回
<div>
<span className='title'>Native Name:</span> {data.nativeName.common}
</div>
但是 api 返回的數據結構看起來不同,例如:
data: Array(12)
0: Object
name: Object
common: "Eswatini"
official: "Kingdom of Eswatini"
nativeName: Object
eng: Object
ssw: Object
改為:
setData([
{
...
nativeName: response.data[0].name.common,
...
}
]);
和
<div>
<span>Native Name:</span> {data[0].nativeName}
</div>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.