[英]React Hooks JS Lint warning useEffect has a missing dependency
I am looking at the documentation from react regarding omitting functions from the list of dependencies because I got this error in my js linter.我正在查看关于从依赖项列表中省略函数的react 文档,因为我在我的 js linter 中遇到了这个错误。 I have tried to amend my code like the docs show, but I feel like I am missing something, because I still get the same error.
我试图像文档显示的那样修改我的代码,但我觉得我错过了一些东西,因为我仍然遇到同样的错误。 I will post my code before and after my attempt.
我会在尝试之前和之后发布我的代码。 Thanks.
谢谢。
warning React Hook useEffect has a missing dependency: 'handleDocumentScrollThrottled'. Either include it or remove the dependency array react-hooks/exhaustive-deps
Code Before attempted fix尝试修复之前的代码
/* Completed useDocumentScrollThrottled utility function */
import { useEffect, useState } from 'react';
import { throttle } from 'lodash';
function useDocumentScrollThrottled(callback) {
const [, setScrollPosition] = useState(0);
let previousScrollTop = 200;
function handleDocumentScroll() {
const { scrollTop: currentScrollTop } = document.documentElement || document.body;
setScrollPosition(previousPosition => {
previousScrollTop = previousPosition;
return currentScrollTop;
});
callback({ previousScrollTop, currentScrollTop });
}
const handleDocumentScrollThrottled = throttle(handleDocumentScroll, 250);
useEffect(() => {
window.addEventListener('scroll', handleDocumentScrollThrottled);
return () =>
window.removeEventListener('scroll', handleDocumentScrollThrottled);
}, []);
}
export default useDocumentScrollThrottled;
Code after attempted fix尝试修复后的代码
...
useEffect(() => {
function doSomething(){
window.addEventListener('scroll', handleDocumentScrollThrottled);
return () =>
window.removeEventListener('scroll', handleDocumentScrollThrottled);
}
doSomething();
}
...
The error will not get resolved, just because you are wrapping the dependency inside another function.错误不会得到解决,只是因为您将依赖项包装在另一个函数中。 The way that's suggested in the docs with the
doSomething
exmaple is to move the function out of your hook's scope.在带有
doSomething
示例的文档中建议的方法是将函数移出钩子的范围。 This is not possible in your case as your handleDocumentScroll
depends on a setter that's only available in the hook.这在您的情况下是不可能的,因为您的
handleDocumentScroll
取决于仅在挂钩中可用的设置器。
Instead you have to:相反,您必须:
Add the dependency of handleDocumentScrollThrottled
to your dependency array like so:将
handleDocumentScrollThrottled
的依赖项handleDocumentScrollThrottled
到您的依赖项数组中,如下所示:
useEffect(() => {
//...
}, [handleDocumentScrollThrottled]);
This of course will not work, as handleDocumentScrollThrottled
is reallocated with every render, therefore causing this effect to trigger every single time.这当然行不通,因为每次渲染都会重新分配
handleDocumentScrollThrottled
,因此每次都会触发此效果。 That's very likely not what you wanted.这很可能不是您想要的。
The solution here is to use a memoized value for handleDocumentScrollThrottled, so that it does not change on every re-render:这里的解决方案是为 handleDocumentScrollThrottled使用一个记忆值,这样它就不会在每次重新渲染时改变:
const handleDocumentScrollThrottled = useMemo(() => {
function handleDocumentScroll() {
const { scrollTop: currentScrollTop } = document.documentElement || document.body;
setScrollPosition(previousPosition => {
previousScrollTop = previousPosition;
return currentScrollTop;
});
callback({ previousScrollTop, currentScrollTop });
}
return throttle(handleDocumentScroll, 250);
}, []);
However, I want to note that (ab)using a setter to set another variable is super hacky and you should probably use a ref
to track your old scroll position instead.但是,我想指出,(ab)使用 setter 设置另一个变量是非常笨拙的,您可能应该使用
ref
来跟踪旧的滚动位置。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.