React:类组件 VS 带 Hooks 的函数组件

2025-06-08

React:类组件 VS 带 Hooks 的函数组件

类组件

在 React Hooks 之前,当我们想要创建一个动态组件时,我们必须创建一个类组件并使用生命周期方法来改变状态,以使其可重用和封装。

通过创建 ES6 类,该类需要在其中扩展React.Component一个render方法,该方法将返回 JSX 标记。此外,我们需要在构造函数中使用 分配初始状态this.state。例如,这里我们使用类创建一个简单的时钟组件。为了使时钟工作,我们必须向我们的类添加生命周期方法。我们将元素放入 DOM,这在 React 中称为mounting。同样,我们从 DOM 中删除元素,这称为unmounting。在 React 中,挂载组件将调用以下四种内置方法:

  • 构造函数()
  • 获取派生状态(来自Props)
  • 使成为()
  • 组件挂载()

更多信息请阅读React Doc:常用的生命周期方法

在我们的示例中,我们在构造函数中设置了初始状态,并定义componentDidMount()为每秒设置一次时间。因此,时钟将每秒使用当前时间更新状态。

class ClockUsingClass extends React.Component {
    constructor(props) {
        super(props)
        this.state = { date: new Date() }
    }

    componentDidMount() {
        this.time = setInterval(() => {
            this.changeTime()
        }, 1000)
    }

    componentWillUnmount() {
        clearInterval(this.time)
    }

    changeTime() {
        this.setState({ date: new Date() })
    }

    render() {
        return (
            <div className="clock">
                <h1>Hello! This is a class component clock.</h1>
                <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
            </div>
        )
    }
}

显然我们可以看到,对于基于类的组件,我们需要几个步骤才能使其能够进行状态改变:

  1. 创建一个具有constructor(props)render()方法的类。
  2. this.state使用构造函数中的语句设置初始状态。
  3. 用于this.setState()更新状态。
  4. 使用诸如 、 等生命周期方法componentDidMount()componentWillUnmount()改变componentDidUpdate()状态

带钩子的函数组件

Hooks 是 React 16.8 中的新增功能。Hooks 最实用的功能是它允许在不使用 class 的情况下使用 state。

最常用的钩子有两种:状态钩子 ——useState和效果钩子 —— useEffect

状态钩子允许你在函数组件中添加状态。this.state我们不需要使用构造函数中的语句设置初始状态,而是可以{ useState }从 React 导入,这样你就可以将初始状态设置为参数。状态钩子将返回一对值:当前状态和更新它的函数。通常,我们会useState像这样使用:

    const [time, setTime] = useState(new Date())

效果钩子将在第一次 DOM 更新时调用。我们可以传入一个函数useEffect,每次 DOM 更新时,函数useEffect也会被调用。此外,效果钩子允许你传入一个数组作为第二个参数,该数组包含将触发效果钩子的所有依赖项。如果任何依赖项发生变化,效果钩子将再次运行。此功能为我们提供了一种更有效的 Ajax 请求方式。你不必每次更新 DOM 时都发出请求,而是可以传入仅在这些值发生变化时发出请求的依赖项。
useEffect可以像这样使用:

    useEffect(() => {
        setInterval(() => {
            changeTime()
        }, 1000)
    })

因此,我们在这里用钩子重写上面创建的时钟

const ClockUsingHooks = props => {
    const [time, setTime] = useState(new Date())

    const changeTime = () => {
        setTime(new Date())
    }

    useEffect(() => {
        const tick = setInterval(() => {
            changeTime()
        }, 1000)
        return () => clearInterval(tick)
    })
    return (
        <div className="clock">
            <h1>Hello! This is a function component clock.</h1>
            <h2>It is {time.toLocaleTimeString()}.</h2>
        </div>
    )
}

概括

对比这两种创建组件的方式,我们可以清楚地看到,钩子需要的代码更少,而且更易于阅读和理解。钩子为我们提供了一种更高效的方法来替换生命周期方法。

查看 repo 来制作一个简单的时钟

鏂囩珷鏉ユ簮锛�https://dev.to/danielleye/react-class-component-vs-function-component-with-hooks-13dg
PREV
使用 GraphQL Helix 构建 GraphQL 服务器
NEXT
翻译数据库查询