在reactjs中使用setTimeout的useEffect



每1秒倒计时减2。但如果我清理setTimeout,代码就会正确运行。有人能解释一下吗?我的结果:https://www.youtube.com/watch?v=NUE-nSLJbiY

    const tabs = ['posts', 'comments', 'albums'];
    const [title, setTitle] = useState('');
    const [posts, setPosts] = useState([]);
    const [type, setType] = useState('posts');
    const [show, setShow] = useState(false);
    useEffect(() => {
        fetch(`https://jsonplaceholder.typicode.com/${type}`)
            .then(res => res.json())
            .then(post => {
                setPosts(post);
            })
    }, [type])
    useEffect(() => {
        document.title = title;
    })
    const [countdown, setCountdown] = useState(180);
    useEffect(() => {
        const id = setTimeout(() => {
            setCountdown(prev => prev - 1);
            console.log(countdown);
        }, 1000);
        // return () => {
        //     clearTimeout(id)
        // }
    })

useEffect在每次渲染中运行。这意味着,当每个值都发生变化时,就会发生渲染,然后会触发另一种效果。

这不是我们想要的。有几种方法可以控制副作用何时发生。

我们应该始终包括接受数组的第二个参数。我们可以选择将依赖项传递到此数组中的useEffect。

如果你想在倒计时值更新后更改倒计时,你应该添加依赖项来使用效果,如下所示:

 useEffect(() => {
        const id = setTimeout(() => {
            setCountdown(prev => prev - 1);
            console.log(countdown);
        }, 1000);
        // return () => {
        //     clearTimeout(id)
        // }
    }, [countdown])

上面的代码在第一次渲染时运行,并且任何时间倒计时值都会更改。事实上,当倒计时减少时,顶部的useEffect触发器也会减少。

  useEffect(() => {
        document.title = title;
    }) //has no dependency

然后文档标题发生了更改,导致了另一次渲染。所以你们处于一个循环中,导致倒计时值递减2。

最新更新