useEffect 的第二个参数, 传空数组和传依赖数组有什么区别?

436 阅读3分钟

useEffect 是 React 中用于处理副作用的 Hook,它的第二个参数是一个依赖数组,用于控制 useEffect 的执行时机。根据传入的依赖数组不同,useEffect 的行为也会有所不同。


1. 不传第二个参数

如果 useEffect 没有第二个参数,它会在每次组件渲染后执行。

行为

  • 组件挂载时执行。
  • 组件每次更新时(包括状态或 props 变化)也会执行。

示例

useEffect(() => {
  console.log('每次渲染后都会执行');
});

使用场景

  • 需要监听所有状态或 props 变化的场景(较少使用,因为可能会导致性能问题)。

2. 传空数组 []

如果 useEffect 的第二个参数是一个空数组 [],它只会在组件挂载和卸载时执行。

行为

  • 组件挂载时执行。
  • 组件卸载时执行清理函数(如果提供了清理函数)。
  • 组件更新时不会执行。

示例

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

  return () => {
    console.log('只在组件卸载时执行');
  };
}, []);

使用场景

  • 只在组件挂载时执行一次的操作(如数据获取、事件监听、定时器等)。
  • 需要在组件卸载时清理资源的操作(如移除事件监听、清除定时器等)。

3. 传依赖数组 [deps]

如果 useEffect 的第二个参数是一个包含依赖项的数组 [deps],它会在组件挂载时以及依赖项发生变化时执行。

行为

  • 组件挂载时执行。
  • 依赖项发生变化时执行。
  • 组件卸载时执行清理函数(如果提供了清理函数)。

示例

useEffect(() => {
  console.log('组件挂载或 count 变化时执行');

  return () => {
    console.log('清理函数:组件卸载或 count 变化时执行');
  };
}, [count]); // 依赖项是 count

使用场景

  • 需要在特定状态或 props 变化时执行的操作(如根据 props 获取数据、监听特定状态的变化等)。

4. 对比总结

行为不传第二个参数传空数组 []传依赖数组 [deps]
组件挂载时执行
组件更新时执行仅当依赖项变化时执行
组件卸载时执行清理函数

5. 示例代码

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

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

  // 不传第二个参数
  useEffect(() => {
    console.log('每次渲染后都会执行');
  });

  // 传空数组
  useEffect(() => {
    console.log('只在组件挂载时执行');

    return () => {
      console.log('只在组件卸载时执行');
    };
  }, []);

  // 传依赖数组
  useEffect(() => {
    console.log('组件挂载或 count 变化时执行');

    return () => {
      console.log('清理函数:组件卸载或 count 变化时执行');
    };
  }, [count]);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>增加</button>
    </div>
  );
}

export default Example;

6. 注意事项

  1. 依赖项要写全

    • 如果 useEffect 中使用了某个状态或 props,但没有将其添加到依赖数组中,可能会导致逻辑错误。
    • 可以使用 ESLint 规则(如 react-hooks/exhaustive-deps)来检查依赖项是否完整。
  2. 避免无限循环

    • 如果 useEffect 中更新了依赖项的状态,且没有正确设置依赖数组,可能会导致无限循环。
  3. 清理函数

    • 如果 useEffect 中执行了需要清理的操作(如事件监听、定时器等),务必返回一个清理函数。

总结

  • 不传第二个参数:每次渲染后都会执行。
  • 传空数组 []:只在组件挂载和卸载时执行。
  • 传依赖数组 [deps]:在组件挂载时以及依赖项变化时执行。

根据具体需求选择合适的依赖数组,可以有效控制 useEffect 的执行时机,优化组件性能。