React Hook useEffect 缺少依赖项:'execute'

Posted

技术标签:

【中文标题】React Hook useEffect 缺少依赖项:\'execute\'【英文标题】:React Hook useEffect has a missing dependency: 'execute'React Hook useEffect 缺少依赖项:'execute' 【发布时间】:2020-03-07 15:08:14 【问题描述】:

尽管尝试了不同的方法,但我似乎无法找到答案。我不断收到错误:

 Line 18:5:  React Hook useEffect has a missing dependency: 'execute'. Either include it or remove the dependency array  react-hooks/exhaustive-deps
printWarnings

在这个文件上:

import useEffect, useState from 'react'

export const createEffect = (fs, dependency) => 
    const[data, setData] = useState()

    const execute = () => (
        fs().then(res => 
            setData(res)
        ).catch(err => 
            // do some magic
        )
    )

    useEffect(() => 
        execute()
        const interval = setInterval(execute, 15000)
        return(() => clearInterval(interval))
    , [dependency])

    return(data)

TLDR 是我需要每 15 秒或在某些全局状态更改时(由 dependency 定义)向 fs() 定义的特定 API 函数发出一个获取请求。我还想捕获数据和任何错误,因此我用几个 then()catch() 块包裹 fs()

当我在功能组件中执行以下代码时,顶部会出现警告:

import createEffect from './components/createEffect'
~~~
let api = new api('http://localhost:8080/v1');
const[status, updateStatus] = useState(true);
const summary = createEffect(api.getSummary, status)

知道如何解决这个问题吗?如果这是做这样的事情的正确方法,我是 React useEffect 的新手,而不是 100%?在我的 useEffect 调用中将 execute 指定为依赖项会导致应用程序不断地重新渲染。我在调用 setInterval() 之前运行 execute(),因为我希望查询每 15 秒运行一次,并且在组件首次呈现时运行。

更多背景信息:我正在制作一个仪表板作为示例项目,并希望每 15 秒或在某些全局状态更改时立即查询多个 api 端点。如果全局状态确实发生了变化,我想将我的 HTTP 轮询从剩下的任何时间重置为 15 秒。

【问题讨论】:

您是否在 useEffect 内部以外的任何地方使用execute?如果没有,您可以简单地将声明移到 useEffect 中以消除警告 如果我在我的 useEffect 函数中移动 execute(),我会得到同样的错误,但这次是关于 fs() 函数:React Hook useEffect has a missing dependency: 'fs' 【参考方案1】:

linting 错误非常直接,只是准确地说明了您需要做什么,要么将 useEffect 的依赖数组保留为空,要么将 execute 函数添加到其中。

基本上,因为您在效果回调中访问 execute 函数,并且由于它是在与效果相同的范围内创建的,所以 React 要求它是一个依赖项。

要解决连续重新渲染的问题,您需要使用useCallback将您的执行函数设为记忆函数

解决它应该很简单:

const execute = useCallback(() => (
    fs().then(res => 
        setData(res)
    ).catch(err => 
        // do some magic
    )
), [setData]);

useEffect(() => 
        execute()
        const interval = setInterval(execute, 15000)
        return(() => clearInterval(interval))
    , [execute])

【讨论】:

我完全按照你的方式做了,但现在 linter 抱怨 fs() 函数 React Hook useCallback has a missing dependency: 'fs' 添加 fs 作为依赖项会导致它不断重新渲染。 你的fs函数来自哪里?您可以更新您的问题以包含它吗? 我不确定我可以提供哪些额外信息? fs 函数是在我导入文件并调用 createEffect() 时传入的函数,因为 createEffect 有两个参数,一个用于执行 fs 的函数和一些 dependency 要添加到 createEffect 内部的 useEffect 调用中。 createEffect 函数像这样导出 export const createEffect = (fs, dependency) => 并像这样调用:createEffect(() => api.getSummary(), status) 如果你问 fs 实际上是什么。这只是对返回承诺的 API 的 fetch() 调用。 如果你像这样调用createEffect createEffect(() => api.getSummary(), status) ,那么你肯定会遇到重新渲染问题,因为每次组件都在组件范围内创建一个新函数() => api.getSummary()考虑重新渲染。在 JS 中,函数是一个对象,React 浅比较会认为它们不同。要解决这个问题,你有一些选择,要么将其从组件中取出,要么使用useCallback 使其成为一个记忆函数。【参考方案2】:

我认为您可以将execute 添加为依赖项,因为函数定义本身并没有改变。如果组件在每次调用后重新渲染,只需调试即可。我认为他们不应该。

【讨论】:

以上是关于React Hook useEffect 缺少依赖项:'execute'的主要内容,如果未能解决你的问题,请参考以下文章

React Hook useEffect 缺少依赖项:'props' 由于 useEffect 中有一行

React Hook useEffect 缺少依赖项(没有在 useEffect 中移动函数)

反应 | React Hook useEffect 缺少依赖项

React Hook useEffect 缺少依赖项:'props'

React Hook useEffect 缺少依赖项

React Hook useEffect 缺少依赖项:'list'