我正在像这样的React函数组件中使用useEffect
:
useEffect(() => {
const handleRouteChangeComplete = () => {
window.scrollTo(0, 0);
userInterface.dispatch(closeNavigation());
};
Router.events.on('routeChangeComplete', handleRouteChangeComplete);
}, []);
useEffect
上的第二个(数组)选项为我带来了以下掉毛错误:
React Hook useEffect has a missing dependency: 'userInterface'. Either include it or remove the dependency array. eslint(react-hooks/exhaustive-deps)
我认为棉绒错误中的两个选项都不正确。
useEffect
的行为将类似于componentDidUpdate
,并且可以多次执行代码userInterface
添加为对useEffect
的依赖项,并且在上下文更新的情况下,它还会多次执行代码我在这里错过了什么吗?还是被迫强迫我写错了逻辑?
我会在此情况下禁用该规则,但我的应用中还有其他4个类似错误的情况。
答案 0 :(得分:2)
存在eslint错误的原因是为了防止由于过时的值而导致难以发现的错误。本质上,lint错误只是告诉您效果中的userInterface变量将过时。
消除该错误并不一定是一个好主意,因为如果您添加更多的依赖项,您可能会不明白为什么事情没有像您期望的那样更新。
关于同一件事的另一篇文章:
useEffect dependency array and ESLint exhaustive-deps rule
https://github.com/facebook/create-react-app/issues/6880
您应该记住的主要事情是确保清理操作,而不管它是否只是在安装时完成,因为有时,如果不清理,效果可能会超出组件的寿命
您有几种不同的解决方法,如果调度是稳定的(基于名称,通常是稳定的),则可以从userInterface变量中拉出调度,然后将其添加到依赖项数组中。 / p>
const { dispatch } = userInterface;
useEffect(() => {
const handleRouteChangeComplete = () => {
window.scrollTo(0, 0);
dispatch(closeNavigation());
};
Router.events.on('routeChangeComplete', handleRouteChangeComplete);
() => {
Router.events.off('routeChangeComplete', handleRouteChangeComplete);
};
}, [dispatch]);
如果无法提取调度值,则可以使用ref来确保以稳定的方式保留最新版本的userInterface。有时这是一项足够常见的任务,您可能希望将逻辑提取到自定义钩子中以获取值的引用。
const userInterfaceRef = useRef(userInterface);
useEffect(() => {
userInterfaceRef.current = userInterface;
}, [userInterface]);
useEffect(() => {
const handleRouteChangeComplete = () => {
window.scrollTo(0, 0);
userInterfaceRef.current.dispatch(closeNavigation());
};
Router.events.on('routeChangeComplete', handleRouteChangeComplete);
() => {
Router.events.off('routeChangeComplete', handleRouteChangeComplete);
};
}, []);
此处似乎具有额外useEffect的原因是,除非您确定确定userInterface永不更改,否则您需要使其保持最新状态,否则userInterfaceRef将会陈旧。我之所以选择userInterface而不是dispatch函数的原因是因为这样您可以在效果内使用userInterface的其他属性而没有任何问题。
如果您不希望重新启动效果而需要依赖于效果,请使用我描述的ref选项来确保您拥有最新的值,而无需每次更改效果都重新运行效果。
如果要在效果中强制将on处理程序添加到某些内容中,则应确保将其清理干净。养成好习惯。