当前位置: 首页 > 知识库问答 >
问题:

javascript - 类组件和函数组件定时器每秒加1的区别?

司空玮
2024-08-21

有大佬帮忙看看这两种的区别吗,功能就是定时器每秒加1
函数组件

useEffect(() => {
        let timer = setInterval(() => {
            setCount(a + 1);
        }, 1000);

        return () => {
            clearInterval(timer)
        }
    }, []);

类组件

componentDidMount() {
        this.timer = setInterval(() => {
            const { n } = this.state
            this.setState({ n: n+1 })
        }, 1000);
    }

为啥类组件可以实现功能,函数组件不行呢?写成函数形式就都可以实现

共有2个答案

黄隐水
2024-08-21

这就是react经典的闭包陷阱了,原因是在函数组件中,a的值一直是初始值,有几种方案可以解决:
1、把a加到useEffect的第二个参数中,即:

useEffect(() => {
        let timer = setInterval(() => {
            setCount(a + 1);
        }, 1000);

        return () => {
            clearInterval(timer)
        }
    }, [a]);

2、利用函数更新:

useEffect(() => {
        let timer = setInterval(() => {
            setCount(p => p + 1);
        }, 1000);

        return () => {
            clearInterval(timer)
        }
    }, []);

3、用useRef保存count的值

闭包陷阱可以搜索引擎搜一下,有很多相关的内容

长孙雅志
2024-08-21

在 React 中,类组件和函数组件(特别是使用了 Hooks 的函数组件)在功能实现上应该是等价的,都能实现定时器每秒加1的功能。不过,你提到的函数组件代码示例中存在一个常见的问题,这会导致它不能正确工作。

函数组件的问题

在你的函数组件示例中,setCount(a + 1); 这行代码存在一个问题:a 并没有在 useEffect 的闭包中被定义或更新,因此它可能是一个未定义的变量或者是一个初始值(取决于 a 的来源),这将导致每次定时器触发时 setCount 接收到的值都是相同的,除非 a 在组件的其他部分被更新,但这在标准的定时器场景中是不适用的。

正确的做法是使用函数组件的状态 count(假设状态变量名为 count 而不是 a),并通过 setCount 函数更新它。这里是一个修正后的函数组件示例:

import React, { useState, useEffect } from 'react';

function FunctionalComponent() {
    const [count, setCount] = useState(0);

    useEffect(() => {
        let timer = setInterval(() => {
            setCount(count => count + 1); // 使用函数形式来确保获取最新的 count 值
        }, 1000);

        return () => {
            clearInterval(timer);
        };
    }, []);

    return <div>{count}</div>;
}

类组件的实现

你的类组件实现是正确的,它通过 setIntervalcomponentDidMount 生命周期方法中设置了一个定时器,并在状态 n 上递增。当组件卸载时,componentWillUnmount(虽然你没有直接展示,但通常会在那里或相应的清理逻辑中调用 clearInterval)将清除定时器,防止内存泄漏。

总结

  • 函数组件和类组件在功能上是等价的,都能实现定时器每秒加1的功能。
  • 在函数组件中,确保你正确地使用了状态更新函数(如 setCount),并考虑使用函数形式来更新状态,以确保获取到最新的状态值。
  • 类组件和函数组件在处理定时器时的主要区别在于它们的生命周期方法和 Hooks 的使用。类组件使用 componentDidMount 和(可能的)componentWillUnmount,而函数组件使用 useEffect
 类似资料:
  • 问题内容: 我一直在玩React,并具有以下仅显示在屏幕上的时间组件: 从React的角度来看,使该组件每秒更新以重新绘制时间的最佳方法是什么? 问题答案: 您需要使用来触发更改,但是还需要在组件卸载时清除计时器,以防止它留下错误和内存泄漏:

  • 我试图将我的类组件转换为功能组件,但我的过滤器不再工作了。 主要的错误是当我想转换listProducts因为我不知道如何定义与useState为这种情况下的preState 如何能为情况更新状态? 这是我的密码 类组件 功能成分

  • 本文向大家介绍展示组件和容器组件有什么区别?相关面试题,主要包含被问及展示组件和容器组件有什么区别?时的应答技巧和注意事项,需要的朋友参考一下 展示组件(Presentational Component) 关注页面的展示效果(外观) 内部可以包含展示组件和容器组件,通常会包含一些自己的DOM标记和样式(style) 通常允许通过this.props.children方式来包含其他组件。 对应用程序

  • 问题内容: 随着React 中钩子的引入,现在的主要困惑是何时将函数组件与钩子和类组件一起使用,因为在钩子的帮助下,甚至可以在函数组件中获得和部分使用。所以,我有以下问题 钩子的真正优点是什么? 何时使用带有钩子的函数组件和类组件? 例如,带有钩子的功能组件不能像类组件那样帮助性能。他们没有执行就不能跳过重新渲染。还有其他原因吗? 提前致谢。 问题答案: 引入和其他特性(例如和)的思想是帮助减少必

  • 我有以下react功能组件来帮助支持react路由器所需的身份验证路由。 我需要将其从功能组件转换为类组件,以便利用React.component的componentDidMount方法。不幸的是,我很难弄清楚如何迁移它。如果我照原样做,我需要复制组件和…rest参数,但我不知道怎么做。我想我可以用这个.props.Component获得组件参数,但我不确定如何拉…rest。我是JSX和ES6的新

  • 问题描述 UI和业务逻辑和数据混杂在一起. class Clock extends React.Component { constructor(props) { super(props); this.state = {time: this.props.time}; this._update = this._updateTime.bind(this); } ren