React 的 useEffect 依赖数组中的 setState

setState in React's useEffect dependency array

在 useEffect 的依赖数组中定义 setState 值背后的想法是什么?

const [someState, setSomeState] = useState();
...
useEffect(() => {
  // Do something
  setSomeState('some value');
}, [setSomeState]);

React Hook useEffect has a missing dependency: 'setSomeState'.
Either include it or remove the dependency array.
eslint(react-hooks/exhaustive-deps)

不确定这个例子是否会导致 eslint 要求在依赖数组中定义 setSomeState,但我在使用 useEffect 编写时看到过这种情况。在这种情况下,React 正在监听什么?我的理解是 useEffect 监听依赖数组中值的变化,但是 setSomeState 会改变吗?我在这里错过了什么?

在这种情况下,不,useState setter 函数永远不会改变,但是 useEffect 不知道它是来自另一个 hook 的函数,它只是看到了一个函数.

考虑这个用例:

const MyComponent = ({ onUpdate }) => {
  const [state, setState] = useState();
  useEffect(() => {
    // state updated, call onUpdate callback with state
    onUpdate(state);
  }, [onUpdate, state]);
  return ...
}

现在父组件可以,给定

<MyComponent onUpdate={onUpdateHandler} />

定义onUpdateHandler

let onUpdateHandler = console.log;

然后在仍然挂载时更改它

onUpdateHandler = state => dispatch({ type: 'SAVE_STATE', state });

通过将回调放在依赖数组中,效果挂钩会看到 onUpdate 的值已更改并再次触发效果。如果它不包含回调,那么它将继续 console.log 状态更新,而不是现在以不同的方式处理它。

值改变的可能性比函数改变的可能性大,但函数值是可以改变的。您可能有一个建议您将挂钩中使用的所有变量添加到依赖项数组的 eslinter,这在大多数情况下是正确的做法。一些例外情况例如,当您希望效果计算 ONLY 当组件通过指定空数组安装时,或者不包括一些变量,这些变量是您 的函数KNOW 在组件的生命周期内永远不会改变,在这些情况下,您可以使用 eslint-disable-next-line react-hooks/exhaustive-deps 覆盖将其取消标记为警告。不过要小心,因为这将禁用 linting 检查,因此如果不注意,错误可能会潜入。