Issue
I have a useEffect
hook that should subscribe to geolocation updates when the component appears, and then unsubscribe when the component disappears. So I pass []
as the effect dependencies since I only want this to run on mount/unmount.
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>
}
Which causes eslint to warn:
React Hook useEffect has missing dependencies:
clearWatch
andstartWatch
. Either include them or remove the dependencyarray.eslint(react-hooks/exhaustive-deps)
So I changed it to this:
useEffect(() => {
startWatch()
return clearWatch
}, [startWatch, clearWatch])
Which causes an infinite render loop.
I'm guessing the infinite loop is caused by the @ionic/react-hooks/geolocation
library which is creating new functions every time useWatchPosition()
is called, making the dependencies look stale.
So should I just disable the check for this line via:
// eslint-disable-next-line react-hooks/exhaustive-deps
Or is there some way I'm missing to do the right thing here?
Solution
Reading the useWatchPosition
source code, you can see that the functions are not created with useCallback
, this means that they are regenerated whenever the hook is called.
You can store a reference to the functions in a ref
, and use the ref.current
to call the function:
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>
}
Answered By - Ori Drori
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.