[英]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.