我不明白为什么当我使用setTimeout函数时,我的反应组件开始到无限的 console.log。一切正常,但 PC 开始滞后。有人说这个函数在超时改变我的状态和重新渲染组件,设置新的计时器等等。现在我需要了解如何清除它是正确的。
setTimeout
export default function Loading() { // if data fetching is slow, after 1 sec i will show some loading animation const [showLoading, setShowLoading] = useState(true) let timer1 = setTimeout(() => setShowLoading(true), 1000) console.log('this message will render every second') return 1 }
清除不同版本的代码无助于:
const [showLoading, setShowLoading] = useState(true) let timer1 = setTimeout(() => setShowLoading(true), 1000) useEffect( () => { return () => { clearTimeout(timer1) } }, [showLoading] )
每次运行时都运行return () => { /*code/* }内部定义的函数(组件安装时的第一次渲染除外)和组件卸载时(如果您不再显示组件)。useEffect``useEffect
return () => { /*code/* }
useEffect``useEffect
沙盒示例。
import { useState, useEffect } from "react"; const delay = 5; export default function App() { const [show, setShow] = useState(false); useEffect( () => { let timer1 = setTimeout(() => setShow(true), delay * 1000); // this will clear Timeout // when component unmount like in willComponentUnmount // and show will not change to true return () => { clearTimeout(timer1); }; }, // useEffect will run only one time with empty [] // if you pass a value to array, // like this - [data] // than clearTimeout will run every time // this value changes (useEffect re-run) [] ); return show ? ( <div>show is true, {delay}seconds passed</div> ) : ( <div>show is false, wait {delay}seconds</div> ); }
import { useState, useEffect, useRef } from "react"; const delay = 1; export default function App() { const [counter, setCounter] = useState(0); const timer = useRef(null); // we can save timer in useRef and pass it to child useEffect(() => { // useRef value stored in .current property timer.current = setInterval(() => setCounter((v) => v + 1), delay * 1000); // clear on component unmount return () => { clearInterval(timer.current); }; }, []); return ( <div> <div>Interval is working, counter is: {counter}</div> <Child counter={counter} currentTimer={timer.current} /> </div> ); } function Child({ counter, currentTimer }) { // this will clearInterval in parent component after counter gets to 5 useEffect(() => { if (counter < 5) return; clearInterval(currentTimer); }, [counter, currentTimer]); return null; }
丹·阿布拉莫夫的文章。