[英]How to add missing dependencies to a useEffect hook that is run only once?
React Hook useEffect 缺少依赖项:“myDate”和“setMyDate”。 包括它们或删除依赖项数组。
如何将缺少的依赖项添加到只运行一次的useEffect
中? 以下示例生成上述警告:
const [ myDate, setMyDate ] = useState(0)
const spinner = useRef(null)
useEffect( () => {
spinner.current = setInterval( () => {
d = Date.now()
if (d < myDate)
setUpdate(d)
}, 997 )
}, [])
如果我包含它们,我会创建一个无限循环,因为setTimeout
更改依赖项的值:
const spinner = useRef(null)
useEffect( () => {
spinner.current = setInterval( () => {
d = Date.now()
if (d < myDate)
setMyDate(d)
}, 997 )
}, [myDate, setMyDate])
如果我删除依赖数组, useEffect
在每次渲染时运行,并设置无限数量的 setIntervals:
const spinner = useRef(null)
useEffect( () => {
spinner.current = setInterval( () => {
d = Date.now()
if (d < myDate)
setMyDate(d)
}, 997 )
})
我还尝试完全删除useEffect
,认为由于spinner
是useRef
,它不会在每个组件渲染上重新分配......但没有:
const spinner = useRef(null)
spinner.current = setInterval( () => {
d = Date.now()
if (d < myDate)
setMyDate(d)
}
还尝试使用功能更新方法,像这样,但 lint 错误仍然存在并且代码不起作用:
const spinner = useRef(null)
useEffect( () => {
spinner.current = setInterval( () => {
d = Date.now()
setMyDate(d => {
if (d < myDate)
setMyDate(d)
}
}, 997 )
}, [setMyDate])
我被卡住了......夹在岩石和坚硬的地方之间! 我该如何解决这个 lint 警告?
似乎对我useCallback()
是将间隔的逻辑分离到一个没有依赖关系的useCallback()
钩子中。 这会记住该函数并确保该函数仅构建在初始组件渲染上。
然后,在效果内部调用使用useCallback()
构建的函数,并将其提供给效果依赖项数组。 然后,只有当useCallback()
函数发生变化时,效果才会重建——它不会,因为它没有依赖关系。
应该从react-hooks
删除 linter 警告
import React, {useState, useEffect, useRef, useCallback} from 'react'
export default function IntervalHook() {
const [ myDate, setMyDate ] = useState(0)
const spinner = useRef(0)
const spinnerFn = useCallback(() => {
spinner.current = setInterval(() => {
const d = Date.now()
setMyDate(d)
}, 997 )
}, [])
useEffect(() => {
spinnerFn()
return () => { // this return statement clears the interval when the component unmounts
if (spinner.current) {
clearInterval(spinner.current)
spinner.current = 0
}
}
}, [spinnerFn])
return (
<span>{myDate}</span>
)
}
解决方案是从setMyDate
函数本身获取myDate
(在我的代码中命名为date
),而不是将其作为依赖项传递。
setMyDate
已记忆,因此不需要作为依赖项传递。
const [myDate, setMyDate] = useState(0);
const spinner = useRef(null);
useEffect(() => {
spinner.current = setInterval(() => {
const d = Date.now();
setMyDate(date => {
if (d < date) {
return d;
}
return date;
});
}, 997);
}, []);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.