在useEffect中,不提供依赖项数组和提供一个空数组有什么区别?

205

我了解到如果 useEffect Hook 提供一个空的依赖数组,它会在每次渲染后运行:

useEffect(() => {
  performSideEffect();
}, []);

但是那种方式和下面的方式有什么区别呢?

useEffect(() => {
  performSideEffect();
});

注意末尾没有[]。这个语法检查插件并没有抛出警告。

5个回答

386

这并不完全相同。

  • 如果给它一个空数组,就像componentDidMount一样,只会运行一次。

  • 如果不给第二个参数,它既像componentDidMount又像componentDidUpdate,即在挂载时首次运行,之后每次重新渲染都会运行。

  • 如果给第二个参数传入一个数组,并包含任何值,例如[variable1],则你的useEffect钩子中的代码将仅在挂载时执行一次,以及当该特定变量(variable1)发生更改时。

您可以在官方文档阅读有关第二个参数以及有关Hooks实际工作原理的更多信息:https://reactjs.org/docs/hooks-effect.html


3
有没有使用场景需要明确地放置 null?难道它不仅仅是在 useEffect 钩子中不放置代码的同义词吗? - Patrick
4
@Patrick useEffect 将在渲染后运行,而仅将代码放在那里将在渲染前运行。 - Rakha Kanz Kautsar
根据https://reactjs.org/docs/hooks-reference.html#conditionally-firing-an-effect中的注释, 传递空数组将导致在componentDidMount之外还在componentWillUnmount上运行。 - R.Nosratabad
当我将依赖数组赋给一个变量(例如:[myList])以显示我使用axios.post插入的列表项时,我看到它在我的网络选项卡中不断发送请求。这会影响我的应用程序性能吗? - KYin
嗯,是的。你基本上正在运行一个无限循环。 - bamtheboozle
显示剩余2条评论

25

@bamtheboozle 的回答进行补充。

如果你从你的 useEffect 返回一个清理函数

useEffect(() => {
  performSideEffect();
  return cleanUpFunction;
}, []);

在每个useEffect代码运行之前,它都会运行,以清除上一个useEffect运行的内容。(除了第一次useEffect运行)


4
你忘记提到清除函数还将始终在卸载时运行。因此,例如,如果依赖数组为空([]),则清除函数仅运行一次:在卸载时运行。请参见这里 的“注意事项”部分(向下滚动)。 - jaquinocode

5

虽然有些晚了,但我想在这里提供一个示例,这是我在阅读以上评论后为了自己的理解而做的:


代码如下:

import './App.css';
import { useEffect, useState } from 'react';

function App() {

  const [name, setName] = useState('John');
   useEffect(()=>{
    console.log("1- No dependency array at all");
  });
  useEffect(()=>{
    console.log("2- Empty dependency array");
  }, []);
  useEffect(()=>{
    console.log("3- Dependency array with state");
  }, [name]);

  const clickHandler = () => {
    setName('Jane');
  }
  return (
    <div className="App">
      <button onClick={clickHandler}>Click to update state</button>
      <p>{`Name: ${name}`}</p>
    </div>
  );
}

export default App;

OUTPUT

On page load

 1- No dependency array at all
 2- Empty dependency array
 3- Dependency array with state
 1- No dependency array at all
 2- Empty dependency array
 3- Dependency array with state
 1- No dependency array at all
 3- Dependency array with state

我在各个地方都看到说一个空数组只会运行一次。我试图使用它来绑定事件处理程序,但是使用空数组时根本不会运行。 - Elias Soares

1

区别在于,如果您不提供空数组依赖项,useEffect()钩子将在挂载和更新时执行。


1
最新的文档详细介绍了这些区别。

https://react.dev/reference/react/useEffect#examples-dependencies

传递一个数组
如果您指定了依赖项,您的 Effect 将在初始渲染之后以及依赖项发生变化后的重新渲染之后运行。
useEffect(() => {}, [a, b]);

传递一个空数组
如果您的 Effect 确实不使用任何响应式值,它将仅在初始渲染后运行(在开发中会运行两次)。这现在会引发一个 linter 警告。
useEffect(() => {}, []);

不传递数组

如果您根本不传递依赖数组,那么您的 Effect 将在每次组件渲染(和重新渲染)之后运行。

useEffect(() => {});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接