繁体   English   中英

如何将缺少的依赖项添加到只运行一次的 useEffect 钩子?

[英]How to add missing dependencies to a useEffect hook that is run only once?

React Hook useEffect 缺少依赖项:“myDate”和“setMyDate”。 包括它们或删除依赖项数组。

如何将缺少的依赖项添加到只运行一次的useEffect中? 以下示例生成上述警告:

const [ myDate, setMyDate ] = useState(0)

const spinner = useRef(null)
useEffect( () => {
    spinner.current = setInterval( () => {
        d = Date.now()
        if (d < myDate)
            setUpdate(d)
    }, 997 )
}, [])

如果我包含它们,我会创建一个无限循环,因为setTimeout更改依赖项的值:

const spinner = useRef(null)
useEffect( () => {
    spinner.current = setInterval( () => {
        d = Date.now()
        if (d < myDate)
            setMyDate(d)
    }, 997 )
}, [myDate, setMyDate])

如果我删除依赖数组, useEffect在每次渲染时运行,并设置无限数量的 setIntervals:

const spinner = useRef(null)
useEffect( () => {
    spinner.current = setInterval( () => {
        d = Date.now()
        if (d < myDate)
            setMyDate(d)
    }, 997 )
})

我还尝试完全删除useEffect ,认为由于spinneruseRef ,它不会在每个组件渲染上重新分配......但没有:

const spinner = useRef(null)
spinner.current = setInterval( () => {
    d = Date.now()
    if (d < myDate)
        setMyDate(d)
}

还尝试使用功能更新方法,像这样,但 lint 错误仍然存​​在并且代码不起作用:

const spinner = useRef(null)
useEffect( () => {
    spinner.current = setInterval( () => {
        d = Date.now()
        setMyDate(d => {
            if (d < myDate)
                setMyDate(d)
        }
    }, 997 )
}, [setMyDate])

我被卡住了......夹在岩石和坚硬的地方之间! 我该如何解决这个 lint 警告?

似乎对我useCallback()是将间隔的逻辑分离到一个没有依赖关系的useCallback()钩子中。 这会记住该函数并确保该函数仅构建在初始组件渲染上。

然后,在效果内部调用使用useCallback()构建的函数,并将其提供给效果依赖项数组。 然后,只有当useCallback()函数发生变化时,效果才会重建——它不会,因为它没有依赖关系。

应该从react-hooks删除 linter 警告

import React, {useState, useEffect, useRef, useCallback} from 'react'

export default function IntervalHook() {

  const [ myDate, setMyDate ] = useState(0)
  const spinner = useRef(0)

  const spinnerFn = useCallback(() => {
    spinner.current = setInterval(() => {
      const d = Date.now()
      setMyDate(d)
    }, 997 )
  }, [])

  useEffect(() => {
    spinnerFn()     
    return () => {  // this return statement clears the interval when the component unmounts
      if (spinner.current) {
        clearInterval(spinner.current)
        spinner.current = 0
      }
    }
  }, [spinnerFn])

  return (
    <span>{myDate}</span>
  )
}

解决方案是从setMyDate函数本身获取myDate (在我的代码中命名为date ),而不是将其作为依赖项传递。

setMyDate已记忆,因此不需要作为依赖项传递。

const [myDate, setMyDate] = useState(0);
const spinner = useRef(null);

useEffect(() => {
  spinner.current = setInterval(() => {
    const d = Date.now();

    setMyDate(date => {
      if (d < date) {
        return d;
      }
      return date;
    });
  }, 997);
}, []);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM