返回

React useEffect 使用指南

前端

React useEffect 是一个内置的 React hook,用于处理组件副作用。副作用是指组件在更新后会执行的任何操作,例如:

  • 在 DOM 中修改元素
  • 发起网络请求
  • 设置定时器
  • 更新存储在 state 之外的变量

useEffect 允许您在组件生命周期的特定时刻执行这些操作。它有以下几个主要特点:

  • useEffect 是一个声明周期钩子(lifecycle hook)。这意味着它会在组件的不同生命周期阶段调用。
  • useEffect 接受两个参数:一个回调函数和一个依赖项数组。
  • 回调函数会在组件渲染后立即调用。如果组件被重新渲染,回调函数也会再次调用。
  • 依赖项数组指定了回调函数何时应该被调用。如果依赖项数组中的任何值发生改变,回调函数就会再次调用。

useEffect 有许多常见用例,包括:

  • 发起网络请求:可以使用 useEffect 来发起网络请求,并在请求成功后更新组件的 state。
  • 设置定时器:可以使用 useEffect 来设置定时器,并在定时器触发时更新组件的 state。
  • 更新存储在 state 之外的变量:可以使用 useEffect 来更新存储在 state 之外的变量,例如:refs 或 context。

useEffect 是一个非常强大的钩子,可以用来处理各种各样的组件副作用。掌握 useEffect 的使用可以帮助您编写更具响应性、更易维护的 React 应用程序。

useEffect 的调用时机

useEffect 会在组件渲染后立即调用。如果组件被重新渲染,useEffect 也会再次调用。

useEffect 有两个调用时机:

  • 初始渲染: 当组件首次渲染时,useEffect 会在组件渲染后立即调用。
  • 状态更新: 当组件的状态发生改变时,useEffect 会在组件重新渲染后调用。

useEffect 的调用时机与组件的生命周期密切相关。组件的生命周期分为四个阶段:

  • 挂载: 当组件首次被渲染到 DOM 中时,组件会进入挂载阶段。
  • 更新: 当组件的状态或属性发生改变时,组件会进入更新阶段。
  • 卸载: 当组件从 DOM 中移除时,组件会进入卸载阶段。
  • 错误处理: 当组件在挂载或更新过程中遇到错误时,组件会进入错误处理阶段。

useEffect 会在组件的挂载和更新阶段调用。当组件首次渲染时,useEffect 会在组件渲染后立即调用。当组件的状态或属性发生改变时,useEffect 会在组件重新渲染后调用。

useEffect 的用法

useEffect 的用法非常简单。它接受两个参数:一个回调函数和一个依赖项数组。

回调函数会在组件渲染后立即调用。如果组件被重新渲染,回调函数也会再次调用。

依赖项数组指定了回调函数何时应该被调用。如果依赖项数组中的任何值发生改变,回调函数就会再次调用。

以下是一个简单的 useEffect 示例:

import React, { useEffect } from 'react';

function MyComponent() {
  useEffect(() => {
    // 这段代码会在组件渲染后立即执行
  }, []);

  return (
    <div>
      <h1>My Component</h1>
    </div>
  );
}

export default MyComponent;

在这个示例中,useEffect 会在组件渲染后立即调用。因为依赖项数组为空,所以回调函数不会再次调用。

如果我们要在组件的状态发生改变时调用回调函数,我们可以将 state 添加到依赖项数组中:

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

function MyComponent() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    // 这段代码会在组件渲染后立即执行,并且会在 count 发生改变时再次执行
  }, [count]);

  return (
    <div>
      <h1>My Component</h1>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

export default MyComponent;

在这个示例中,useEffect 会在组件渲染后立即调用。当 count 发生改变时,useEffect 会再次调用。

useEffect 的常见用例

useEffect 有许多常见用例,包括:

  • 发起网络请求:可以使用 useEffect 来发起网络请求,并在请求成功后更新组件的 state。
  • 设置定时器:可以使用 useEffect 来设置定时器,并在定时器触发时更新组件的 state。
  • 更新存储在 state 之外的变量:可以使用 useEffect 来更新存储在 state 之外的变量,例如:refs 或 context。
  • 清理资源:可以使用 useEffect 来清理资源,例如:定时器、网络请求或 DOM 事件监听器。

以下是一些具体的示例:

  • 发起网络请求:
import React, { useEffect, useState } from 'react';

function MyComponent() {
  const [data, setData] = useState([]);

  useEffect(() => {
    fetch('https://example.com/api/data')
      .then(response => response.json())
      .then(data => setData(data));
  }, []);

  return (
    <div>
      <h1>My Component</h1>
      <ul>
        {data.map(item => <li key={item.id}>{item.name}</li>)}
      </ul>
    </div>
  );
}

export default MyComponent;

在这个示例中,useEffect 会在组件渲染后立即调用。它会发起一个网络请求,并在请求成功后更新组件的 state。

  • 设置定时器:
import React, { useEffect, useState } from 'react';

function MyComponent() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    const interval = setInterval(() => {
      setCount(count + 1);
    }, 1000);

    return () => {
      clearInterval(interval);
    };
  }, []);

  return (
    <div>
      <h1>My Component</h1>
      <p>Count: {count}</p>
    </div>
  );
}

export default MyComponent;

在这个示例中,useEffect 会在组件渲染后立即调用。它会设置一个定时器,每隔 1 秒钟就会更新组件的 state。

  • 更新存储在 state 之外的变量:
import React, { useEffect, useRef } from 'react';

function MyComponent() {
  const ref = useRef(null);

  useEffect(() => {
    ref.current.focus();
  }, []);

  return (
    <div>
      <h1>My Component</h1>
      <input ref={ref} />
    </div>
  );
}

export default MyComponent;

在这个示例中,useEffect 会在组件渲染后立即调用。它会将 ref.current 设置为输入元素,然后将焦点设置到输入元素上。

  • 清理资源:
import React, { useEffect } from 'react';

function MyComponent() {
  useEffect(() => {
    const eventListener = window.addEventListener('resize', () => {
      // 做一些事情
    });

    return () => {
      window.removeEventListener('resize', eventListener);
    };
  }, []);

  return (
    <div>
      <h1>My Component</h1>
    </div>
  );
}

export default MyComponent;

在这个示例中,useEffect 会在组件渲染后立即调用。它会添加一个事件监听器,并在组件卸载时将其移除。