发布于 2026-01-05 8 阅读
0

React Hooks 简介 HappyReact HappyReact

React Hooks简介

HappyReact

HappyReact

React Hooks 一直是大家关注的焦点,现在热度已经消退,我想写一篇关于它们的简短介绍,并介绍一些具体的用例。

React Hooks 是在 React 版本 16.8 中引入的,它允许我们在函数组件中使用曾经仅限于类组件的功能(例如内部状态、生命周期钩子等)。

这很棒,因为编写函数式组件通常更受社区青睐,它们具有诸多优势,例如:代码更易读、更易维护、更易于测试,并且通常遵循更佳的编程实践。例如,创建展示型组件、容器组件和业务逻辑组件比使用基于类的组件要容易得多

今天,我们只介绍两种最常用的钩子:useStateuseEffect

要充分利用本课程,请确保您掌握 React 的基础知识,特别是内部状态和生命周期钩子的概念。

为了方便学习,您可以克隆以下仓库,我们将使用这两个钩子将类组件转换为函数式组件。这些组件位于 `<components_name>`/components/ExampleUS和 `<components_name> ` 下/components/ExampleUE

使用状态

好的,我们有以下基于类的组件:

class ExampleUS extends React.Component {
  state = {
    value: ''
  }

  onChange = event => {
    this.setState({
      value: event.target.value
    })
  }

  render() {
    return (
      <article>
        <h1>useState example</h1>

        <input
          type="text"
          value={this.state.value}
          onChange={this.onChange}
        />

        <p>
          Value: {this.state.value}
        </p>
      </article>
    )
  }
}
Enter fullscreen mode Exit fullscreen mode

它的作用是允许用户输入内容,输入的内容会保存在组件的内部状态中,并在下方显示,如下所示:

上述组件的渲染

该组件需要一个内部状态,因此在 16.8 版本之前使用基于类的方法是有意义的,但useState钩子将允许我们将其转换为其函数式对应物。

useState 语法

语法useState非常容易理解:

const [value, setValue] = useState('')
Enter fullscreen mode Exit fullscreen mode

这里value是我们要绑定状态的变量,setState是用来更新状态的方法,传递给该方法的参数useState是状态的默认值。很简单,对吧?

转换组件

从类组件过渡到函数式组件只需两个简单的步骤:

1)首先,我们将组件的声明改为函数式声明。

// Changed the declaration of the component
const ExampleUS = () => {
  state = {
    value: ''
  }

  // onChange is now assigned to a constant variable
  const onChange = event => {
    this.setState({
      value: event.target.value
    })
  }

  // Removed the render method,
  // Functional components directly return the JSX to be rendered
  return (
    <article>
      <h1>useState example</h1>
      <input
        type="text"
        value={this.state.value}
        onChange={this.onChange}
      />
      <p>
        Value: {this.state.value}
      </p>
    </article>
  )
}
Enter fullscreen mode Exit fullscreen mode

2) 现在让我们移除类上下文(this)和状态的所有痕迹

const ExampleUS = () => {
  // Removed the state declaration

  // Removed the call to this.setState()
  const onChange = event => {}

  // Removed all calls to the context
  return (
    <article>
      <h1>useState example</h1>
      <input
        type="text"
        onChange={onChange}
      />
      <p>
        Value:
      </p>
    </article>
  )
}
Enter fullscreen mode Exit fullscreen mode

最终结果

好了,现在我们可以使用useState前面提到的语法来创建内部状态。

最终组件如下所示(别忘了导入钩子):

import React, { useState } from "react"

const ExampleUS = () => {
  // We declare the state and the method to update it
  const [value, setValue] = useState('')

  // On input, call setValue with the new state value
  const onChange = event => {
    setValue(event.target.value)
  }

  // Bind the input to the state value and display it
  return (
    <article>
      <h1>useState example</h1>
      <input
        type="text"
        value={value}
        onChange={onChange}
      />
      <p>
        Value: {value}
      </p>
    </article>
  )
}
Enter fullscreen mode Exit fullscreen mode

使用效果

在这个例子中,我们有以下组件:

class ExampleUE extends React.Component {
  state = {
    url: ''
  }

  /**
   * Fetch a random dog photo and save its URL in our state
   */
  componentDidMount() {
    fetch("https://dog.ceo/api/breeds/image/random")
      .then((res) => res.json())
      .then(data => this.setState({
        url: data.message
      }))
  }

  render() {
    return (
      <article>
        <h1>useEffect example</h1>
        <img src={this.state.url} alt="dog picture"/> 
      </article>
    )
  }
}
Enter fullscreen mode Exit fullscreen mode

在挂载点,我们获取一张图片,将其保存到内部状态并显示出来,大致如下:

上述组件的渲染

重点在于componentDidMount组件挂载时(即插入到 DOM 树中时)调用的生命周期钩子。我们将使用这个useEffect钩子在函数式组件中实现完全相同的功能。

useEffect 语法

再次强调,这个钩子的语法简单易懂,使用方便:

useEffect(() => {
  // ...
})
Enter fullscreen mode Exit fullscreen mode

它接受一个回调函数作为第一个参数,该回调函数将在每次组件渲染时触发

但在我们的例子中,我们只想在组件挂载时触发一次,对吗?

为此,我们可以传递useEffect第二个参数,一个变量数组,该数组中的变量只有在被修改时才会触发回调(而不是在组件每次渲染时都触发)。我们还可以传递一个空数组(`$('$(''))` [])来告诉回调仅在组件挂载和卸载时触发,代码如下所示:

useEffect(() => {
  // ...
}, [])
Enter fullscreen mode Exit fullscreen mode

转换组件

我们将跳过这部分,因为它与之前的版本相比变化不大。

最终结果

// Don't forget to import both hooks
import React, { useState, useEffect } from "react"

const ExampleUE = () => {
  const [url, setUrl] = useState('')

  // On component mount, the callback is called
  // Fetch retrieves a picture and saves it in our internal state
  // The second parameter tells useEffect
  // to only be triggered on mount and dismount
  useEffect(() => {
    fetch("https://dog.ceo/api/breeds/image/random")
      .then((res) => res.json())
      .then(data => setUrl(data.message))
  }, [])

  return (
    <article>
      <h1>useEffect example</h1>
      <img src={url} alt="dog picture" />
    </article>
  )
}
Enter fullscreen mode Exit fullscreen mode

总结

React Hooks 是 React 库的一大亮点,它们提供了诸多优势,并显著提升了开发者的体验。

需要注意的是,React 库中还有许多其他的 Hook,有些比其他的更常用。我建议您阅读官方文档,它写得非常出色。

其他参考资料包括:

感谢阅读!如果您有所收获,欢迎在 Twitter 上关注我@christo_kade,我会分享所有关于 React、Vue 和整个 JS 生态系统的最新博文 ❤️

文章来源:https://dev.to/christopherkade/introduction-to-react-hooks-1e0l