所以我是一个超级新手。我有一些代码,我使用fetch从API获取数据(我创建的,结构像{'userData': {'overall': {'rank': '10', 'level': '99', 'xp': '200000000'}}),我在屏幕上显示它。它工作了好几个小时,现在突然没有触及任何代码,它坏了。如果我发出API请求,然后刷新页面,它将显示数据。但是当我再次刷新页面时,它告诉我&;Uncaught TypeError: Cannot read properties of undefined (reading 'overall')&;我不知道我做错了什么,我想知道是否有人可以帮助我,因为我不知道它是如何变成未定义的,它读取它很好,然后刷新它变成未定义。下面是组件
的代码function Activities() {
let name = "three-dawg";
function fetchPlayerData(name){
fetch(URL)
.then(response => response.json())
.then(data => setPlayerData(data));
};
function refreshPage() {
window.location.reload(false)
}
const [playerData, setPlayerData] = useState([]);
useEffect(() => {fetchPlayerData(name)}, [name]);
return (
<div>
Hello {playerData._id}
<button onClick={() => {
fetchPlayerData(name)
refreshPage()
}}>load player</button>
<ul>
<li>{playerData.userData.overall.rank}</li>
</ul>
</div>
);
}
const [playerData, setPlayerData] = useState([]);
你的初始状态是一个空数组,所以这是你第一次渲染时的值。数组没有userData
属性,所以当你试图访问playerData.userData.overall
时,你会得到一个异常。
你要么需要让你的初始数据看起来像你的真实数据,这样playerData.userData.overall.rank
是有效的,或者,更可能的是,你需要添加代码来检查你是否仍然有初始数据,并在等待加载完成时呈现不同的东西。null
或undefined
将更容易检查,所以您可能希望使用其中一个作为初始状态。
const [playerData, setPlayerData] = useState(null);
useEffect(() => {fetchPlayerData(name)}, [name]);
if (!playerData) {
return <div>Loading...</div>
}
return (
<div>
// ...the rest of your code
</div>
)
您可能还想删除重新加载页面的代码。
这个问题很容易解决。只要加上"?"在获取所有数据之后。
return (
<div>
Hello {playerData?._id}
<button onClick={() => {
fetchPlayerData(name)
refreshPage()
}}>load player</button>
<ul>
<li>{playerData?.userData.overall.rank}</li>
</ul>
</div>
);
数据获取是异步的,所以当你呈现屏幕时,它首先呈现初始状态,这是一个空数组。获取数据需要时间。所以,通过添加一个问号,渲染器检查数据是否存在,然后才渲染你的组件。