8

这是我编写的一些可以正常工作的示例代码:

useEffect(() => {
  if (!rolesIsLoading && rolesStatus === 200) {
    customer.roles = rolesData.roles;
  }
}, [rolesIsLoading, rolesStatus]);

我在控制台中收到此警告:

React Hook useEffect 缺少依赖项:“customer.roles”和“rolesData.roles”。要么包含它们,要么删除依赖数组 react-hooks/exhaustive-deps

问题是,代码现在可以正常工作,并且在某些情况下,当我按照指示添加此类依赖项时,我最终会遇到无限循环或其他问题。

当您遇到类似情况时,如果您就如何解决此问题提供任何建议,我将不胜感激。

4

1 回答 1

11

反应文档

有条件地触发效果

效果的默认行为是在每次完成渲染后触发效果。这样,如果其依赖项之一发生更改,则始终会重新创建效果。

但是,在某些情况下,这可能有点矫枉过正,例如上一节中的订阅示例。我们不需要在每次更新时都创建一个新订阅,只要源道具发生了变化。

要实现这一点,请将第二个参数传递给 useEffect,它是效果所依赖的值数组。我们更新后的示例现在看起来像这样:

useEffect(
 () => {
   const subscription = props.source.subscribe();
   return () => {
     subscription.unsubscribe();
   };
 },
 [props.source],
);

因此,从上面的练习中我们看到,依赖数组的目的是有条件地触发一个效果。

您收到的警告是因为您在效果函数中使用了一些外部(从效果的角度)变量,而您在依赖数组中没有提到这些变量。

React 担心您可能会在未来的渲染中为这些变量获取新值,并且由于您的效果使用它们,React“默认意图”是使用新变量值重新运行该效果。因此,您的效果将始终是最新的。

因此,如果/当这些变量在未来发生变化时,您需要考虑是否要重新运行您的效果。

基本建议:

  • 将它们添加到依赖数组
  • 如果它们从不改变,就没有区别
  • 如果它们发生变化,请添加一些条件来决定是否应该根据新变量值做某事
  • 如果它们仅在引用中更改,但在值中没有更改(如函数、数组、对象等),您可以使用useCallbackoruseRef钩子从第一次渲染中保留这些变量的“引用”,而不是在每次渲染时都获得新的引用使成为。
于 2019-09-18T10:30:55.640 回答