Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用eslint deps对订阅/取消订阅的useEffect依赖项作出反应_Javascript_Reactjs_Ionic Framework_React Hooks - Fatal编程技术网

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>
}