“React Hook useEffect 缺少依赖项”函数警告

pad*_*otk 7 javascript reactjs react-hooks

所以我有这个使用 useEffect() 钩子的 React 组件:

const [stateItem, setStateItem] = useState(0);

useEffect(() => {
  if (condition) {
    myFunction();
  }
}, [stateItem]);

const myFunction = () => {
  return 'hello';
}
Run Code Online (Sandbox Code Playgroud)

React 向我发出警告,提示“myFunction”缺少依赖项。我(认为我)理解为什么,并且我已经阅读了许多类似的问题,要求或多或少相同的事情,但答案始终是“将您的函数移至 useEffect 挂钩”。如果不是从不同的地方调用 myFunction,这会很好,例如:

...
return (
  <Button onClick={() => myFunction()} />
);
Run Code Online (Sandbox Code Playgroud)

因此我不能将我的函数放入 useEffect 挂钩中。

类似问题的一个答案是将函数放在组件之外,但这需要我将大量数据传递给我的函数,例如 const myFunction(stateItem, setStateItem, someProp) => { stuff };

当有多个函数需要传递许多 props、state hooks 等时,这会变得非常乏味。

除了在 useEffect 钩子上方放置 linterignore 注释之外,还有什么更实际的事情可以做吗?我发现这些事情使得使用反应钩子变得非常不切实际。

cbd*_*per 6

我对此有疑问。

React 总是试图让你的效果保持最新。如果您不传递依赖项数组,React 将在每次渲染后运行该效果,以防万一。

这将在每个渲染上运行

useEffect(()=> {
  // DO SOMETHING
});
Run Code Online (Sandbox Code Playgroud)

如果您传递一个空数组,则基本上表明您的效果不依赖于任何内容,并且仅运行一次是安全的。

这只会运行一次

useEffect(()=> {
  // DO SOMETHING
},[]);
Run Code Online (Sandbox Code Playgroud)

如果您填充依赖项数组,则表示您的效果取决于这些特定的事物,如果其中任何一个发生变化,则效果需要再次运行,否则,则不必运行。

someProp仅当或发生更改时才会运行someFunction

useEffect(()=> {
  // DO SOMETHING
},[someProp,someFuction]);
Run Code Online (Sandbox Code Playgroud)

注意:记住函数、对象和数组是通过引用进行比较的

所以,基本上你的选择是:

  • 将函数移至效果主体。
  • 添加它来做依赖数组

如果您选择将其添加到数组中,则需要决定以下事项:

如果该函数被修改,您是否需要再次运行您的效果?

如果这是真的,只需将其添加到依赖项数组中,React 将在每次函数更改时重新运行您的效果。

如果这不是真的,请将您的函数包装到 a 中useCallback,以便您可以在渲染之间保持其引用相同。您还可以向 中添加一个依赖项数组来useCallback控制何时需要重新创建函数。

EXTRA该函数需要重新创建,但您不想重新运行。

  • 添加一些变量来useRef()跟踪效果是否运行过一次,并在效果中写入一个检查以停止效果(如果它之前运行过)。喜欢:
const effectHasRun_ref = useRef(false);
useEffect(()=>{
  if (effectHasRun_ref.current === true) {
    return;
  }
  else {
    // RUN YOUR EFFECT
    effectHasRun_ref.current = true;
  }
},[yourFunction]);
Run Code Online (Sandbox Code Playgroud)


Leo*_*ici -1

TLDR:将 myFunction 添加到依赖项数组中,如下所示

React useEffect 有一个叫做依赖数组的东西,它的作用基本上可以帮助你做出反应,知道何时重新运行效果。基本上,您应该将所有定义的内容放在效果之外。

在此效果中,您将 stateItem 作为此效果的依赖项,这意味着每次更改时反应都会重新运行此效果。现在你可能已经猜到你正在使用myFunction它,它在效果之外也定义好了,这意味着反应应该知道更新的时间,以便它知道。要修复此警告,只需将函数在依赖项数组中放置一个项目,如下所示。

const [stateItem, setStateItem] = useState(0);

useEffect(() => {
  if (condition) {
    myFunction();
  }
}, [stateItem, myFunction]);

const myFunction = () => {
  return 'hello';
}
Run Code Online (Sandbox Code Playgroud)

  • 我从警告消息中怀疑这就是 React 建议做的事情。然而,对于函数,我想知道这是否有意义,因为函数不会更改/更新,因此除了抑制警告之外,不会出于其他原因进行跟踪。 (4认同)