我正在创建useMyData
钩子,它执行以下操作:
- 根据输入参数从某些 API 获取原始数据 (
dependencies
( - 使用昂贵的函数转换数据 (
expensiveMath
( - 记忆并返回结果
我的函数如下所示:
function useMyData(...dependencies) {
const raw = useFetch(mkUrl(dependencies), dependencies)
const data = useMemo(() => expensiveMath(raw), dependencies)
return data
}
raw
只依赖于dependencies
数组,expensiveMath
只取决于raw
这意味着它只取决于输入参数(dependencies
(。
我想避免在输入参数未更改时调用expensiveMath
。
但问题是我收到这个 ESLint 错误:
ESLint 错误:
React Hook useMemo has a missing dependency: 'raw'.
Either include it or remove the dependency array
react-hooks/exhaustive-deps
我不能使用raw
作为useMemo
的依赖项,因为它是长度不可预测的大量复杂对象数组。
我的用例的最佳实践是什么?
如果您不在依赖项中包含raw
,那么您的代码将不起作用,因为当获取完成时raw
它将更改。
在第一次呈现时,调用useFetch
并启动请求,然后返回某个占位符。如果useFetch
是这个库,那么这个占位符是一个具有loading: true
和data: undefined
的对象。接下来useMemo
运行,并在该加载占位符上执行expensiveMath
。
在第二次渲染中,useFetch
现在已完成并返回实际数据。但由于useMemo
没有将 raw 列为依赖项,因此会重用记忆的值。您不会对真实的原始数据执行expensiveMath
。
因此,解决方法是将raw
放在依赖项数组中:
const data = useMemo(
() => expensiveMath(raw),
[raw]
)
现在,expensiveMath
将在抓取完成后重新运行。我认为没有必要将dependencies
放入useMemo中,因为它们未在代码的这一部分使用。
我不能将 raw 用作 useMemo 的依赖项,因为它是长度不可预测的大量复杂对象数组。
大小无关紧要。useMemo
只是在以前的值和新值之间执行引用相等性检查。因此,只要useFetch
以合理的方式编写,以便在没有任何更改时返回稳定的引用,它就会起作用。