发布于 2026-01-06 0 阅读
0

React 的 useEffect Hook

React 的 useEffect Hook

最初,由于我之前一直使用基于类的 React 框架,所以很难理解 hooks。

我遇到的最难的钩子是 useEffect。

很高兴我理解了,现在我想向你展示 useEffect 是什么以及如何使用它。


简要介绍

React 16.8 版本中加入了 Hooks,使我们能够在编写函数式组件的同时,仍然使用状态和其他 React 特性(如生命周期方法),而无需使用类。

有些钩子函数还允许你在函数式组件中设置状态。这听起来似乎没什么特别的,但与类组件不同,类组件中你需要修改组件的状态才能让 React 检测到,而函数式组件中也需要告知 React 何时发生了状态变化。


useEffect钩子

useEffect 是一个钩子函数,用于在需要执行副作用时使用。

手动更改 DOM 或获取数据就是这方面的例子。

默认情况下,此钩子会在每次渲染后运行,这意味着每次 React 需要重新渲染时都会运行。


用例效果

如果您了解 React 的类式生命周期方法:

useEffect 是以下情况的替代方案:

  • 组件挂载
  • componentDidUpdate
  • componentWillUnmount

如果您是因为从 16.8 版本之后才开始使用 useEffect 而对此不了解,请不要担心。如果您想在组件执行以下操作时执行某些操作,useEffect 非常有用:

  • 首批渲染图
  • 已更新/重新渲染
  • 即将进行清理

此外,与传统的类式生命周期方法不同,useEffect 运行时不会阻塞浏览器。这通常会让你的应用响应速度更快,尤其是在钩子函数中运行更多逻辑时。

使用 useEffect

组件挂载时和重新渲染时运行

这个钩子的经典用法(在官方文档中也有说明)是动态更新网站的标题。

在这个例子中,网站的标题会在每次渲染时更新。

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

const Component = () => {
  [notifications, setNotifications] = useState(0);

  useEffect(() => {
    document.title = `Oliver - {notifications} pending notifications`;
  });

  // ...

  return (
    // ...
  );
};
Enter fullscreen mode Exit fullscreen mode

这样使用时,钩子可以代替:

  • 组件挂载
  • componentDidUpdate

组件挂载时、重新渲染时以及组件被清除时运行

另一个用例是订阅 API 并响应更新。通常,在清除组件之前,还需要先取消订阅该 API。否则,逻辑会继续运行。

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

const Component = () => {
  [someState, setSomeState] = useState({});

  useEffect(() => {
    const subscription = subscribeToApi(() => {
      // ...
      setSomeState(...);
    });
    return () => {
      subscription.unsubscribe();
    };
  });

  // ...

  return (
    // ...
  );
};
Enter fullscreen mode Exit fullscreen mode

这样使用时,钩子可以代替:

  • 组件挂载
  • componentDidUpdate
  • componentWillUnmount

仅当组件挂载时运行

useEffect 实际上接受第二个参数,即它的依赖项。通过这些依赖项,您可以微调 React 何时运行 useEffect。

如果你希望钩子只在挂载时运行一次,则传递一个空数组。

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

const Component = () => {
  [someState, setSomeState] = useState({});

  // This runs only once.
  // Pay attention to the
  // second argument '[]'.
  useEffect(() => {
    // ...
    setSomeState(...);
  }, []);

  // ...

  return (
    // ...
  );
};
Enter fullscreen mode Exit fullscreen mode

这样使用时,钩子可以代替:

  • 组件挂载

自定义 useEffect 运行时间

最后一种方法是每次特定依赖项发生更改时运行 useEffect。

不要传递空数组,而是传递您希望 useEffect 做出反应的状态变量。

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

const Component = () => {
  [someState, setSomeState] = useState({});

  // This runs each time
  // someState changes
  useEffect(() => {
    // Could be an API call or whatever
    validateSomeStateCorrectness(someState);
  }, [someState]);

  // ...

  return (
    // ...
  );
};
Enter fullscreen mode Exit fullscreen mode

这样使用时,这个 Hook 实际上并不像任何生命周期方法那样做出反应。它只会在 React 检测到状态变量的值发生变化时触发。


离开之前

如果您想阅读更多类似内容,欢迎在TwitterLinkedIn上关注我。

我非常乐意将你纳入我不断壮大的优秀朋友行列!

本文最初发表于我的个人博客

文章来源:https://dev.to/oliverjumpertz/react-s-useeffect-hook-69c