【问题标题】:using setInterval and clearInterval to change counter in react app使用 setInterval 和 clearInterval 更改反应应用程序中的计数器
【发布时间】:2021-10-04 21:35:44
【问题描述】:

我正在尝试创建一个带有“浴缸”和 2 个按钮的应用程序。浴缸有 5 个水位。 当您单击第一个按钮时,浴缸每 2 秒填充一个级别,直到达到 5。另一个按钮将浴缸排干直到级别 0。increaseWaterLevel 和 reductionWaterLevel 函数只触发一次,我不知道为什么。

import React, { useState } from "react";

const App = () => {
  const [waterLevel, setWaterLevel] = useState(0);
  let fillTub;
  let drainTub;
  const increaseWaterLevel = () => {
    if (waterLevel < 5) {
      const newWaterLevel = waterLevel + 1;
      setWaterLevel(newWaterLevel);
    } else {
      clearInterval(fillTub);
    }
  };

  const decreaseWaterLevel = () => {
    if (waterLevel > 0) {
      const newWaterLevel = waterLevel - 1;
      setWaterLevel(newWaterLevel);
    } else {
      clearInterval(fillTub);
    }
  };

  return (
    <div>
      <div>Bathtub</div>
      <button
        onClick={() => {
          fillTub = window.setInterval(increaseWaterLevel, 2000);
        }}
      >
        increaseWaterLevel
      </button>
      <button
        onClick={() => {
          drainTub = window.setInterval(decreaseWaterLevel, 2000);
        }}
      >
        decreaseWaterLevel
      </button>
    </div>
  );
};

export default App;

更新计数器正在工作但没有停止并且水位保持在 0。我做错了什么?

import React, { useState } from "react";

const App = () => {
  const [waterLevel, setWaterLevel] = useState(0);
  const [intervalId, setIntervalId] = useState(0);

  const increaseWaterLevel = () => {
    const newWaterLevel = setInterval(() => {
      if (waterLevel > 4) {
        clearInterval(intervalId);
      } else {
        setWaterLevel((prevWaterLevel) => prevWaterLevel + 1);
      }
    }, 2000);
    setIntervalId(newWaterLevel);
  };

  const decreaseWaterLevel = () => {
    const newWaterLevel = setInterval(() => {
      if (waterLevel > 0) {
        setWaterLevel((prevWaterLevel) => prevWaterLevel - 1);
      } else {
        clearInterval(intervalId);
      }
    }, 2000);
    setIntervalId(newWaterLevel);
  };

  return (
    <div>
      <div>Bathtub</div>
      <button onClick={increaseWaterLevel}>increaseWaterLevel</button>
      <button onClick={decreaseWaterLevel}>decreaseWaterLevel</button>
    </div>
  );
};

export default App;

【问题讨论】:

  • 看这里,了解如何使用 setInterval 和 clearInterval sebhastian.com/setinterval-react
  • 这是一个很好的教程!但我还是有点困惑。我的 setInterval 没有跟踪状态变化,所以它是无限计数的。
  • @Gareth 检查我的答案,然后进行一些研究,例如“如何在 setState 之后获取更新的变量”。这对我帮助很大!

标签: javascript reactjs setinterval use-state


【解决方案1】:

首先让我说我开始学习反应就像 1 周前,我 仍然有一些疑问,即使这段代码可能真的很糟糕 有效,但我仍然想提供帮助,所以这是代码。

这里的主要问题是 useState 函数是一个 async 函数,它不会实时更新您的变量,因此在这种情况下,在没有 useEffect 的情况下检查 waterLevel 值将不起作用。

import React, { useState, useEffect } from "react";

const App = () => {
const [waterLevel, setWaterLevel] = useState(0);
const [actionType, setActionType] = useState();

useEffect(() => {
  const interval = setInterval(() => {
    if (actionType == "increase" && waterLevel < 5)
      setWaterLevel(waterLevel + 1);
    if (actionType == "decrease" && waterLevel > 0)
      setWaterLevel(waterLevel - 1);
  }, 2000);
  return () => clearInterval(interval);
}, [actionType, waterLevel]);

return (
   <div>
   <div>Bathtub</div>
   <button onClick={() => setActionType("increase")}>
     increaseWaterLevel
   </button>
   <button onClick={() => setActionType("decrease")}>
     decreaseWaterLevel
   </button>
   <h1>{waterLevel}</h1>
 </div>
 );
};

export default App;

【讨论】:

  • ActionTypes 是一个非常好的方法!您的解决方案效果很好,在这种情况下,我肯定必须阅读 useEffect 。谢谢大家的贡献!
  • @Gareth 如果通过接受它来接近答案,我很高兴能够帮助你
猜你喜欢
  • 1970-01-01
  • 2011-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-11
  • 1970-01-01
相关资源
最近更新 更多