useEffect 无限运行

时间:2021-05-25 14:16:45

标签: javascript reactjs react-hooks use-effect

我正在使用钩子进行反应,我使用 useEffect 对 API 进行第一次调用,并在 setinterval 的帮助下每隔几秒调用一次 API,这是一个显示我需要执行的大量数据的屏幕它的自动滚动使用第三个 useEffect 来管理时间,但它导致每秒进行一次 API 调用,从而导致性能问题。

如何让自动滚动的 useEffect 不影响其他两个 useEffects?

 const [datos, setDatos]=useState([]);
  const [autoScroll, setAutoScroll] = useState(true);
  const [top, setTop] = useState(false);
  const [step, setStep] = useState(0);
const goTop = () => {
     
    const windowHeight = "innerHeight" in window ? window.innerHeight : 
    document.documentElement.offsetHeight;
    const body = document.body;
    const html = document.documentElement;
    const docHeight = Math.max(body.scrollHeight, body.offsetHeight, 
    html.clientHeight,  html.scrollHeight, html.offsetHeight);
    const windowBottom = windowHeight + window.pageYOffset;

    if (windowBottom >= docHeight && step >1 ) {
       setTop(true)       
    } 
};

const getData = async() => {
  try {
    return await axios.get(`localhost:xxxx/api/data`)
      .then(function(response) {
        return response;
      }).then(function(response) {
        setDatos(response.data.data);
      })
      .catch(function(error) {

        console.log('error catch', (error))
      });
  } catch (error) {
    console.log('error', error)
  }
}

let haveData = false;
useEffect(() => {
  if (!haveData) {
    getData(999);
    haveData = true;
  }
  const interval = setInterval(() => {
    getData(999);
  }, 1200000)
  return () => clearInterval(interval)
}, [])

useEffect(() => {
  if (autoScroll) {
    const timer = setInterval(() => {
      setStep(step + 1)

      if (top === false) {
        scroll.scrollMore(25);
      } else {

        window.scrollTo({
          top: 0,
          behavior: "smooth"
        });
        setTop(false);
      }
    }, 1000);

    goTop();

    return () => clearInterval(timer);
  }
}, [step, autoScroll]);

2 个答案:

答案 0 :(得分:1)

当您调用 setStep(step+1) 时,您会更改 step,从而触发效果挂钩。

尝试将其更改为像这样的 mutator 函数:

setStep(step => step+1)

然后从钩子 deps 数组中删除 step

答案 1 :(得分:1)

只想快点指出

useEffect(() => {
 ...
}, [step, autoScroll]);

每次 stepautoScroll 更改值时,依赖项都会运行它。尝试在该函数中放入 console.log 以进行确认。

相反,第一个带有空依赖项数组的 useEffect 可以工作,因此它在挂载期间只会运行一次。为什么会有帮助?因为您的 setInterval 无论如何都会运行,因此您不必一次又一次地定义它。

以下是 useEffect 的一些用法说明。 https://javascript.plainenglish.io/hooks-part-2-useeffect-2fa1a377c124