Javascript 使用eslint deps对订阅/取消订阅的useEffect依赖项作出反应
我有一个Javascript 使用eslint deps对订阅/取消订阅的useEffect依赖项作出反应,javascript,reactjs,ionic-framework,react-hooks,Javascript,Reactjs,Ionic Framework,React Hooks,我有一个useffecthook,它应该在组件出现时订阅地理位置更新,然后在组件消失时取消订阅。因此,我将[]作为效果依赖项传递,因为我只希望它在装载/卸载时运行 import { useWatchPosition } from "@ionic/react-hooks/geolocation" import React, { useEffect } from "react" function SiteMap() { const { currentPosition, startWatch,
useffect
hook,它应该在组件出现时订阅地理位置更新,然后在组件消失时取消订阅。因此,我将[]
作为效果依赖项传递,因为我只希望它在装载/卸载时运行
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>
}
这会导致无限的渲染循环
我猜无限循环是由@ionic/react hooks/geolocation
库引起的,该库每次调用useWatchPosition()
时都会创建新函数,使依赖项看起来过时
因此,我应该通过以下方式禁用此行的检查:
// eslint-disable-next-line react-hooks/exhaustive-deps
或者我在这里没有做正确的事情吗?阅读
useWatchPosition
,您可以看到函数不是使用useCallback创建的,这意味着每当调用钩子时都会重新生成它们
您可以将对函数的引用存储在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>
}
功能站点地图(){
const{currentPosition,startWatch,clearWatch}=useWatchPosition()
常量startWatch href=useRef(startWatch)
const clearWatchRef=useRef()
useffect(()=>{
clearWatch.current=clearWatch//更新的clearWatch
})
//订阅/取消订阅组件装载/卸载时的地理位置。
useffect(()=>{
startwatchhref.current()
return()=>clearWatchRef.current()
}, [])
返回{/*…*/}
}
在每次渲染后,是否会立即调用clearWatch
,但决不能多次调用startWatch
?不会,因为clearWatch
是作为组件卸载时将调用的函数返回的。它没有被调用就返回了-returnclearwatch
。等等,我以为只要依赖项发生变化或卸载,就会调用effect cleanup函数。清理功能只会在卸载时被调用?你说得对。在这种情况下,它将在每次重新加载时调用。我已经更新了答案。请注意,由于已知REF是静态的,因此您甚至不需要将其包含在依赖项列表中(尽管包含它们并不重要)。更新-调用startWatch
后,clearWatch
函数应包含更新的watchId
,并设置watchId
,因此,每当组件重新加载时,您应该更新clearWatchRef.current
。不要在组件中多次调用startWatch
。
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>
}