我只是想用React Hooks更改标题和内容状态,但我在页面上看到了一个数字,谷歌搜索显示了一堆与setInterval和Timeout如何生成键或值有关的内容,但我不知道它们为什么会出现在页面上。我可以使用一个空的div来隐藏它,但我很好奇我是否做错了什么,如果我使用一个类而不是一个函数,值会迅速增加,我的CPU也会耗尽。
function MyComponent (){
const [heading, setHeading] = useState('React(Loading)')
const [content, setContent] = useState('Loading...')
return(
<main>
<h1>{heading}</h1>
<p>{content}</p>
{
setTimeout(() =>{
setHeading('React(Loaded)')
setContent('Loaded')
}, 2000)} // should change the values, which it does with addition of a number
</main>
);
}
生成的页面显示在此处顺便说一句,我尝试使用onload函数来做同样的事情,但什么也没发生。
setTimeout返回一个数字,用于在使用clearTimeout时标识超时。这就是为什么你会在内容下面看到数字。
要隐藏数字,您应该将setTimeout移动到return函数之外。此外,您应该在return语句中尽可能少地使用JS,只在那里使用JSX,以使组件更加清晰易读。
但是仅仅将setTimeout移动到return语句之前是不够的。该函数将在每次渲染时运行,有很多事情可以触发重新渲染-状态更改或父级重新渲染。因此,每次重新渲染时,都会设置一个新的超时。超时本身会更新一个状态,该状态会触发一个渲染,该渲染会触发setTimeout,因此您正在创建一个无限循环。
因此,您只想调用setTimeout一次-您可以使用useEffect,它只有在依赖数组更改时才会重新运行,但如果将其保留为空,它将只运行一次,因为不会发生任何更改,也永远不会触发重新运行。
function MyComponent (){
const [heading, setHeading] = useState('React(Loading)')
const [content, setContent] = useState('Loading...')
useEffect((
setTimeout(() =>{
setHeading('React(Loaded)')
setContent('Loaded')
}, 2000)
), []);
return(
<main>
<h1>{heading}</h1>
<p>{content}</p>
</main>
);
}
因此,通过使用上面的答案,我们得到以下错误
Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function
原因再次是setTimeout返回一个数字,最终的答案是将代码作为一个单独的函数使用,如下所示:
useEffect( timeOutFunction, [])
function timeOutFunction() {
setTimeout(() => {
setHeading('React(Loaded)')
setContent('Loaded'), 2000)
}