Ale*_*yne 2 javascript reactjs ionic-framework react-hooks
我有一个useEffect
钩子,它应该在组件出现时订阅地理定位更新,然后在组件消失时取消订阅。所以我[]
作为效果依赖传递,因为我只希望它在挂载/卸载时运行。
import { useWatchPosition } from "@ionic/react-hooks/geolocation"
import React, { useEffect } from "react"
function SiteMap() {
const { currentPosition, startWatch, clearWatch } = useWatchPosition()
// Subscribe/Unsubscribe to geo location on component mount/unmount.
useEffect(() => {
startWatch()
return clearWatch
}, [])
return <svg>{/* ... */}</svg>
}
Run Code Online (Sandbox Code Playgroud)
这导致 eslint 发出警告:
React Hook useEffect 缺少依赖项:
clearWatch
和startWatch
. 包括它们或删除依赖项array.eslint(react-hooks/exhaustive-deps)
所以我把它改成了这样:
useEffect(() => {
startWatch()
return clearWatch
}, [startWatch, clearWatch])
Run Code Online (Sandbox Code Playgroud)
这会导致无限渲染循环。
我猜无限循环是由@ionic/react-hooks/geolocation
每次useWatchPosition()
调用时都会创建新函数的库引起的,使依赖项看起来过时。
所以我应该通过以下方式禁用对这一行的检查:
// eslint-disable-next-line react-hooks/exhaustive-deps
Run Code Online (Sandbox Code Playgroud)
或者我有什么方法可以在这里做正确的事情?
阅读useWatchPosition
源代码,你可以看到函数不是用 来创建的useCallback
,这意味着只要调用钩子就会重新生成它们。
您可以在 a 中存储对函数的引用ref
,并使用ref.current
调用该函数:
function SiteMap() {
const { currentPosition, startWatch, clearWatch } = useWatchPosition()
const startWatchRef = useRef(startWatch)
const clearWatchRef = useRef()
useEffect(() => {
clearWatch.current = clearWatch // the updated clearWatch
})
// Subscribe/Unsubscribe to geo location on component mount/unmount.
useEffect(() => {
startWatchRef.current()
return () => clearWatchRef.current()
}, [])
return <svg>{/* ... */}</svg>
}
Run Code Online (Sandbox Code Playgroud)