首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为订阅/取消订阅响应useEffect依赖关系,使用eslint详尽的-deps

为订阅/取消订阅响应useEffect依赖关系,使用eslint详尽的-deps
EN

Stack Overflow用户
提问于 2020-01-09 19:47:31
回答 1查看 624关注 0票数 2

我有一个useEffect钩子,它应该在组件出现时订阅地理位置更新,然后在组件消失时取消订阅。因此,我将[]作为效果依赖项传递,因为我只希望它在挂载/卸载上运行。

代码语言:javascript
复制
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>
}

这会使埃林特发出警告:

React useEffect缺少依赖项:clearWatchstartWatch。要么包含它们,要么删除依赖项array.eslint(react-hooks/exhaustive-deps)

所以我把它改成了这个

代码语言:javascript
复制
  useEffect(() => {
    startWatch()
    return clearWatch
  }, [startWatch, clearWatch])

这会导致无限的呈现循环。

我猜想无限循环是由@ionic/react-hooks/geolocation库引起的,它每次调用useWatchPosition()时都会创建新函数,这使得依赖项看起来很陈旧。

因此,我是否应该通过以下方式禁用这一行的检查:

代码语言:javascript
复制
// eslint-disable-next-line react-hooks/exhaustive-deps

还是我错过了什么方法来做正确的事?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-01-09 19:51:13

阅读useWatchPosition 源代码,您可以看到函数不是用useCallback创建的,这意味着每当调用钩子时都会重新生成函数。

您可以在ref中存储对函数的引用,并使用ref.current调用该函数:

代码语言:javascript
复制
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>
}
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59671138

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档