【useEffect Hook】在组件中执行副作用操作

引言

useEffect 是 React 中用于处理副作用的 Hook,它允许你在函数组件中执行类似于类组件生命周期方法的操作。通过 useEffect,你可以在组件挂载、更新和卸载时执行某些操作。

常见副作用操作:

  1. AJAX 请求:获取或提交数据。
  2. 计时器:设置定时任务。
  3. 异步操作:处理异步逻辑。
  4. 更改真实的 DOM 对象:直接操作 DOM 元素。
  5. 本地存储:读取或写入浏览器的本地存储。
  6. 其它会对外部产生影响的操作:例如订阅事件等。

语法

useEffect(() => {
  // 副作用逻辑
  console.log('组件渲染后执行');

  // 可选的清理逻辑
  return () => {
    console.log('组件卸载或重新渲染前执行');
  };
}, [依赖数组]);

依赖数组:

  • 空数组 []useEffect 只会在组件挂载和卸载时执行。
  • 有值 [value]useEffect 会在组件挂载、卸载以及 value 发生变化时执行。
  • 不提供依赖数组useEffect 会在每次渲染后执行。

执行时机

useEffect 的副作用函数在真实的 UI 渲染完成之后执行。因此它的执行是异步的,不会阻塞浏览器的渲染过程。这确保了用户界面的流畅性,避免了由于同步执行副作用而导致的卡顿。

详细解释

1. 组件挂载时执行

当组件首次挂载时,useEffect 会执行一次。你可以在这里进行初始化操作,例如发起网络请求或设置定时器。

import React, { useEffect } from 'react';

function MyComponent() {
  useEffect(() => {
    console.log('组件挂载时执行');
  }, []); // 空数组表示只在组件挂载和卸载时执行

  return <div>My Component</div>;
}

2. 组件更新时执行

当组件的依赖项发生变化时,useEffect 会再次执行。你可以指定一个或多个依赖项,只有当这些依赖项发生变化时,useEffect 才会触发。下面的例子实现了当在输入框输入时,网页的标题也会随之改变,而且网页标题的更改稍稍滞后于输入框的更改,说明useEffect是异步执行的,且在组件渲染之后。

import { useEffect, useState } from 'react'

export default function Test() {
  const [value, setValue] = useState('')

  useEffect(() => {
    console.log('提供了依赖项,useEffect会在每次依赖项发生变化后执行', value);
    // 副作用操作
    document.title = `当前标题: ${value}`;
  }, [value])
  return (
    <div>
      <input type="text" value={value} onChange={(e) => setValue(e.target.value)} />
    </div>
  )
}

效果图:
【useEffect Hook】在组件中执行副作用操作_第1张图片

3. 组件卸载时执行

你可以返回一个清理函数,该函数会在组件卸载或依赖项变化前执行。这对于清除副作用(如取消网络请求或清除定时器)非常有用。

import React, { useEffect } from 'react';

function MyComponent() {
  useEffect(() => {
    console.log('组件挂载时执行');

    // 设置定时器
    const timer = setInterval(() => {
      console.log('每秒执行一次');
    }, 1000);

    // 返回清理函数
    return () => {
      console.log('组件卸载或重新渲染前执行');
      clearInterval(timer); // 清除定时器
    };
  }, []); // 空数组表示只在组件挂载和卸载时执行

  return <div>My Component</div>;
}

4. 每次渲染后执行

如果不提供依赖数组,useEffect 会在每次渲染后执行。这通常不是推荐的做法,因为它会导致不必要的副作用执行。

import { useEffect, useState } from 'react'

export default function Test() {
  const [value, setValue] = useState('')

  useEffect(() => {
    console.log('不提供依赖项,useEffect会在每次渲染后执行', value)
  })
  return (
    <div>
      <input type="text" value={value} onChange={(e) => setValue(e.target.value)} />
    </div>
  )
} 

演示图:
【useEffect Hook】在组件中执行副作用操作_第2张图片

最佳实践

  1. 尽量缩小依赖数组:只包含真正需要监听的依赖项,以减少不必要的副作用执行。
  2. 使用清理函数:对于需要清理的副作用(如定时器、事件监听),务必提供清理函数,以防止内存泄漏。
  3. 避免副作用逻辑复杂化:将复杂的副作用逻辑拆分为多个 useEffect,每个 useEffect 处理单一职责,使代码更易维护。

通过合理使用 useEffect,你可以有效地管理组件的副作用,提升应用的性能和可维护性。

你可能感兴趣的:(React,react.js,useEffect)