[英]Designing React Hooks prevent react-hooks/exhaustive-deps warning
I am designing a hook to fetch data only when the hooks dependencies change. 我正在设计一个挂钩,仅在挂钩依赖项更改时才获取数据。 It works as expected but I receive the linter warnings:
它可以按预期工作,但是我收到了linter警告:
React Hook useEffect was passed a dependency list that is not an array literal. This means we can't statically verify whether you've passed the correct dependencies.
and 和
React Hook useEffect has missing dependencies: 'data', 'errorHandler', 'route', and 'successHandler'. Either include them or remove the dependency array. If 'successHandler' changes too often, find the parent component that defines it and wrap that definition in useCallback.
As far as I am aware I do not want all these vars in my dependencies as I don't want to fire this hook when these change, I only want to fire it when the dependencies I pass change. 据我所知,我不希望所有这些var都存在于我的依赖项中,因为我不想在这些更改时触发此钩子,我只想在我通过的依赖项更改时触发它。
Question: How can I design useFetch()
hook in a way that coincides with the hooks linter standards (if my design pattern is not up to par, please elaborate on how best this should be accomplished). 问题:如何以与钩子linter标准一致的方式设计
useFetch()
钩子(如果我的设计模式不符合标准,请详细说明应如何最好地实现)。
My useFetch()
hook 我的
useFetch()
挂钩
function useFetch(
{
route,
data = {},
successHandler,
errorHandler,
},
dependencies = []) {
const [loading, setLoading] = useState(true);
useEffect(() => {
setLoading(true);
postJson({route}, data)
.then(
res => {
if(isFunction(successHandler)) successHandler(res);
},
({responseJSON: err}) => {
if(isFunction(errorHandler)) {
errorHandler(err);
} else {
notify({text: err.message || messages.saveFailed(), cssClass: 'error'});
}
}
)
.finally(() => {
setLoading(false);
});
}, dependencies);
return loading;
}
Component using useFetch()
使用
useFetch()
组件
function MyComponent({data, selectedReviewId, setField}) {
const loading = useFetch({
route: 'foo.fetchData',
data: {crrType, clientId, programId, userId},
successHandler: d => setField([], d) // setField() will set data with the value fetched in useFetch()
}, [selectedReviewId]);
return loading ? <SpinnerComponent/> : <div>{data.foo}</div>;
}
You have passed dependency as array but on the receiving end, it's essentially a single variable pointing to an array. 您已经将依赖项作为数组传递了,但是在接收端,它实质上是指向数组的单个变量。 Lint rule of
useEffect()
requires that you pass dependencies in square brackets like done in following code. useEffect()
的useEffect()
规则要求您像下面的代码中那样在方括号中传递依赖项。
Now some technical stuff. 现在介绍一些技术资料。 Remember what's generating the warning.
记住是什么产生警告。 It's the lint which checks code syntactically.
皮棉语法地检查代码。 It doesn't go into semantics.
它没有涉及语义。 Semantically, your list of dependencies is correct, as you are passing an array but syntactically, it's not being passed as an array ie it's a single variable not passed in square brackets (like this
[dependencies]
) (which is something lint is looking for). 从语义上讲,您的依赖项列表是正确的,因为您正在传递数组,但是从语法上讲,它不是作为数组传递的,即它是一个未在方括号中传递的单个变量(例如
[dependencies]
)(这是lint正在寻找的东西) )。 So in order to satisfy lint, you should write: 因此,为了满足皮棉的要求,您应该编写:
useEffect(
() => { // implementation of function },
[dependencies]
);
Further, as you are sending an array of dependencies, you can also use spread operator, like this: 此外,在发送依赖项数组时,还可以使用传播运算符,如下所示:
useEffect(
() => { // implementation of function },
[...dependencies]
);
This will spread the array elements inside array operator by Babel transpiler. 这将通过Babel Transpiler将数组元素散布到数组运算符中。 Lint will also remain quiet.
皮棉也将保持安静。
The eslint
warning is right - you should include those as dependencies. eslint
警告是正确的-您应将其包括为依赖项。 For example, in your MyComponent
if data
changes, and it is not in your dependency list, your useEffect
hook will be calling fetch will outdated data
. 例如,在
MyComponent
如果data
发生更改,并且不在依赖列表中,则useEffect
挂钩将调用fetch将过期的data
。
Same applies to others - it's advised to add those to your dependencies list. 同样适用于其他人-建议将它们添加到您的依赖项列表中。
For the first error, it is probably ok - even though not ideal. 对于第一个错误,这可能没问题-即使不理想。 You have a dynamic dependencies list -
eslint
can't be sure if you have all the required stuff in there. 您有一个动态的依赖项列表
eslint
不确定其中是否包含所有必需的内容。
Your solution is probably going to work - but it is very fragile. 您的解决方案可能会起作用-但它非常脆弱。 If your
dependencies
happen to change (eg additional elements, or removed elements) 如果您的
dependencies
发生更改(例如,其他元素或已删除的元素)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.