React Hooks 中的 useEffect(副作用)

useEffect 是什么?

useEffect 是一个 React Hook,它允许你将组件与外部系统同步

当我们在 React 中使用 useEffect 这个 Hook 时,实际上是在告诉 React 在特定情况下执行我们定义的副作用函数。这种副作用函数可以处理一些与组件渲染结果无关的操作,例如数据获取、订阅事件、手动操作 DOM 等。

副作用函数作为 useEffect 的第一个参数传入。每当组件更新并重新渲染时,React 都会检查是否有副作用函数需要执行。但是,如果你想控制副作用函数的执行时机,可以传入第二个参数,这个参数是一个依赖数组。只有当依赖数组中的值发生变化时,副作用函数才会执行。

  • 如果将依赖数组设置为空数组:[],副作用函数将仅在组件第一次渲染时执行。这对于只需要执行一次的副作用操作非常有用,比如进行初始化的数据获取或订阅事件。
 // 挂载时执行,页面创建时只执行一次
  useEffect(() => {
    
    
    console.log("建立游戏连接");
  }, []);

  • 如果依赖数组中包含某个值:[value],副作用函数将在组件首次渲染时执行,以及该值发生变化时执行。这对于根据特定值来执行操作非常有用,比如根据输入值来查询数据。
 // 更新时,当监听的依赖项变动时触发
  useEffect(() => {
    
    
    console.log("当前游戏为:", optionValue);
  }, [optionValue]);
  • 如果不传递依赖数组,副作用函数将在每次组件重新渲染时都会执行。这可以用来处理具备实时更新需求的副作用操作,比如实时订阅数据或通过 WebSocket 接收数据。

  • 销毁时执行

 // 销毁时
  useEffect(() => {
    
    
    return () => {
    
    
      console.log("已断开连接");
    };
  }, []);

生命周期钩子函数为主执行:分别在每个钩子函数中,实现一个完整功能的部分效果

以功能为主执行:一个功能的所有效果放在一起实现

在开发中更常用的是 【以功能为主执行】,将代码整合,放在一起

 useEffect(() => {
    
    
    console.log("1 建立游戏连接:", optionValue, num, str);
    return () => {
    
    
      console.log("2 断开游戏连接:", optionValue);
    };
  }, [optionValue, num, str]);

它的执行流程为:1挂载:1 2更新:21 3卸载:2

  • 需要作为依赖项的值:Effect 中用到的可变的值,比如:prpos/state/组件内创建的变量等

  • 不需要则作为依赖项的值:组件外创建或导入的变量、函数的等

总的来说 useEffect 是 React 提供的一个 Hook,用于处理副作用操作。它的主要功能可以总结如下:

  1. 定义副作用函数:通过 useEffect,我们可以定义一个副作用函数,用于执行与渲染无关的操作。副作用函数可以包含任意代码,比如数据获取、订阅事件、手动操作 DOM 等。

  2. 控制副作用函数的执行时机:useEffect 的第一个参数是副作用函数。每当组件完成渲染后,React 就会检查是否需要执行副作用函数。通过传递一个依赖数组作为 useEffect 的第二个参数,可以控制副作用函数的执行时机。

  3. 组件挂载时执行副作用函数:当组件首次渲染时,副作用函数会被执行一次。这对于一些初始化操作非常有用,比如进行数据获取、订阅事件等。

  4. 组件更新时重新执行副作用函数:如果依赖数组中的任何依赖项发生变化,副作用函数会被重新执行。这使得我们可以根据特定的值或状态来更新副作用操作,以保持与组件的同步。

  5. 组件卸载时执行清理操作:如果我们在副作用函数中返回一个清理函数,它将在组件卸载时被调用。这可以用来取消订阅、清除定时器或执行其他必要的清理操作。

通过使用 useEffect,我们可以在函数式组件中处理副作用操作,并且能够灵活地控制这些操作的执行时机和清理。这为我们提供了一种方便的方式来管理组件的副作用,使得代码更简洁、可维护。

在使用它的依赖项时应注意 当使用 useEffect 时,我们应该根据具体开发场景来注意依赖项的设置。以下是一些常见开发场景和相应的依赖项注意事项:

  1. 数据获取和异步操作:

    • 如果副作用函数需要使用组件内部的状态或属性来触发数据获取,那么在依赖项中包含这些相关的状态或属性。
    • 如果数据获取是通过网络请求等异步操作进行的,需要确保依赖项不会在每次数据更新时重新触发数据获取。可以使用 useEffect 的清理函数来取消之前的请求。
  2. 监听事件或订阅:

    • 如果副作用函数需要监听全局事件或进行订阅,需要在依赖项中包含相关的事件或订阅源。
    • 在清理函数中,需要取消事件监听或取消订阅,以避免内存泄漏。
  3. 使用第三方库或外部资源:

    • 如果副作用函数使用了第三方库或外部资源(比如地图、音频等),需要根据文档或库提供的使用方式设置依赖项。
    • 在清理函数中,需要进行资源释放或销毁操作,以确保不会出现资源泄漏或内存溢出。
  4. 组件内部状态更新:

    • 如果副作用函数中使用了组件内部的状态,并且希望在状态更新时重新执行副作用函数,需要在依赖项中包含这些状态。
    • 需要注意避免创建闭包陷阱,可以使用 useCallback 或函数式更新来确保正确的依赖项设置。
  5. 优化性能:

    • 如果副作用函数不依赖任何值或状态,且其效果可以被忽略,可以省略依赖项,以避免不必要的重复执行。
    • 如果副作用函数只需要在组件挂载和卸载时执行一次,可以将依赖项设置为空数组 []

根据具体的开发场景和需求,我们需要仔细考虑哪些值和状态对副作用函数的正确执行起到关键作用,并相应地设置依赖项,以保证正确性和性能。

猜你喜欢

转载自blog.csdn.net/wbskb/article/details/132051598