在 useEffect 堆栈中调用的每个函数都必须包装在 useCallback 中吗?

Every function called in `useEffect` stack must be wrapped in `useCallback`?

我是 React 的新手,在我看来,如果您在 useEffect 中使用函数,则整个堆栈必须包含在 useCallback 中才能符合 linter。

例如:

const Foo = ({} => {
  const someRef = useRef(0);

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

  const handleProcessWithRef = useCallback((event) => {
    someRef.current = event.clientY;
  }, []);

  const startProcessWithRef = useCallback(() => {
    window.addEventListener('mousemove', handleProcessWithRef);
  }, [handleProcessWithRef]);

  ...
});

我想知道是否有不同的模式,我不必使整个链从 useEffect 开始调用 startProcessWithRef 包装在 useCallback 中并具有依赖性。我不是说它好或坏,我只是看看是否有更好的选择,因为我是新手,不知道有没有。

编写示例的惯用方式类似于:

Note the importance of removing the event listener in the effect cleanup function.

TS Playground

import {useEffect, useRef} from 'react';

const Example = () => {
  const someRef = useRef(0);

  useEffect(() => {
    const handleMouseMove = (event) => { someRef.current = event.clientY; };
    window.addEventListener('mousemove', handleMouseMove);
    return () => window.removeEventListener('mousemove', handleMouseMove);
  }, [someRef]);

  return null;
};

如果您更喜欢在效果挂钩之外定义函数,则需要 useCallback:

import {useCallback, useEffect, useRef} from 'react';

const Example = () => {
  const someRef = useRef(0);

  const updateRefOnMouseMove = useCallback(() => {
    const handleMouseMove = (event) => { someRef.current = event.clientY; };
    window.addEventListener('mousemove', handleMouseMove);
    return () => window.removeEventListener('mousemove', handleMouseMove);
  }, [someRef]);

  useEffect(updateRefOnMouseMove, [updateRefOnMouseMove]);

  return null;
};