有很多关于eslint规则react-hooks/exhaustive-deps的帖子,还有关于memoizations hooks
useMemo
和useCallback
的良好用法,它们通常被过度使用,但我还没有找到任何好的回答以下问题:
如何在应用程序开发的早期阶段混合使用
useMemo
和useCallback
不进行过度优化的策略,同时仍然遵循react-hooks/exhaustive-deps规则?
例如,如果我有一个
useEffect
,它将在值更改时执行一个函数,它将执行以下操作:
// Simplest example I've found
myFunction(() => value);
useEffect(() => { myFunction(); }, [value])
但这里 eslint 会告诉我,我需要将
myFunction
传递给依赖项数组,这将导致无限循环,除非我将 myFunction
放入 useCallback
中,并在依赖项数组中使用 value
(和 myFunction
在 useEffect
) 之一。
我不确定这里的最佳实践是什么,我想避免对如此简单的函数使用记忆化,因为
useCallback
在性能方面实际上要求很高。
我对一个主题和另一个主题进行了一些研究,但我没有找到有关这两个主题的任何有用信息。
我已经看到这个答案解释了何时不使用
useEffect
,但我认为仍然有一些用例需要在useEffect
回调内部使用组件中定义的函数。
一般来说,强烈建议保留
react-hooks/exhaustive-deps
规则。只有当某个函数(或其调用的函数)中没有任何内容引用从它们派生的 props、状态或值时,从依赖项列表中省略该函数才是安全的。对于函数,基本上有两种方法可以避免警告。
function DependencyTest({ value }) {
useEffect(() => {
const myFunction = () => value;
myFunction();
}, [value]);
}
function DependencyTest({ value }) {
const myFunction = useCallback(() => value, [value]);
useEffect(() => {
myFunction();
}, [myFunction]);
}
为了避免性能问题,我会选择第一个。 React 文档中提到了同样的事情:https://legacy.reactjs.org/docs/hooks-faq.html#is-it-safe-to-omit-functions-from-the-list-of-依赖关系
编辑: 归根结底,Eslint 只是一个愚蠢的风格检查器。严格遵循 eslint 规则编写整个代码只会导致性能不佳的代码。这一切都是为了找到真正适合您的用例的东西:
如果您觉得所有依赖项都已覆盖,请忽略 eslint,无需将该函数添加到依赖项列表中。
推荐的方法是将函数放在 useEffect 块中/使用记忆。最终为什么 eslint 强制具有依赖功能? - 因为人们会犯错误,所以会忘记依赖关系。拥有规则集比让人们忘记一些规则要好。