我的帖子与其说是一个问题,不如说是一个问题。在react中,为了从API中获取数据,我们使用了钩子useEffect。但为什么不直接与各州合作来管理重新渲染呢?(见下面的例子)
import React from "react"
export default function App() {
const [starWarsData, setStarWarsData] = React.useState({})
const [isLoaded, setIsLoaded] = React.useState(false)
if (!isLoaded) {
const randomIndex = Math.floor(Math.random()*50)
fetch(`https://swapi.dev/api/people/${randomIndex}`)
.then(res => res.json())
.then(data => setStarWarsData(data))
setIsLoaded(true)
}
return (
<div>
<pre>{JSON.stringify(starWarsData, null, 2)}</pre>
<button onClick={() => setIsLoaded(false)}>Load random charachter</button>
</div>
)
}
如您所见,我用一个简单的if语句来管理重新呈现。你能告诉我为什么我应该使用useEffect获取数据,而不是上面展示的方式吗?
Thanks in advance
嗯,我实际上认为这是一个很好的问题:)
从技术上讲,你在这里做的事情是有效的,因为你要确保取回只发生一次,不会重新触发无限渲染。
但是在渲染阶段执行副作用有一些缺陷:
- 你在渲染阶段中使用useState,这意味着你有无限次重新触发渲染阶段的危险。
- 让我们假设你只想在mount阶段完成后一次获取数据(use effect with empty dependency array或componentDidMount event in class components) -你可以摆脱isLoaded状态,只使用一个状态来存储数据,因为代码只会触发一次,你不必担心isLoaded状态下的重新渲染。
- 在每次渲染中,你都要检查isLoaded是否为false,这是多余的,因为我们确切地知道什么时候我们想要重新获取数据。(仅在挂载后,并在点击"加载随机字符"按钮后)
使用useEffect-你要确保数据抓取不会中断UI,并且不会通过使用依赖项数组不情愿地重新触发渲染。通过使用这个钩子,代码更加清晰,并且您可以确切地知道何时调用它。
(旁注-记住setState是异步的,这可能会导致意外的渲染,如果你依赖于该状态的前一个值,也会导致一些问题)