【问题标题】:Progressbar re renders previous state when i reset the state当我重置状态时,进度条重新呈现以前的状态
【发布时间】:2021-02-23 01:59:35
【问题描述】:

我有一个进度条,它接收一个值作为宽度 当我单击“重置”按钮时,它会将状态重置为 0 并按预期工作 但是,当我在 进度条是 100% 宽度,它将继续增加 状态

如何防止这种情况发生?

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

function ProgressBar({ value = 0 }) {
  const [percent, setPercent] = useState(value);
  useEffect(() => {
    setPercent(value);
  }, [value]);
  return (
    <>
      {value.toFixed(2)}%
      <div
        style={{ display: "flex", width: "100%", border: "1px solid black" }}
      >
        <div
          style={{
            border: "1px solid black",
            backgroundColor: "red",
            height: "0.5rem",
            transition: 0,
            width: `${percent}%`
          }}
        ></div>
      </div>
    </>
  );
}

export default function App() {
  const [percent, setPercent] = useState(0);
  const [willReset, setWillReset] = useState(false);

  const step = 100 / 3;

  useEffect(() => {
    function updateProgress() {
      if (!willReset) {
        setTimeout(() => {
          if (percent + step > 100) {
            setPercent(percent + (100 - percent));
          } else {
            setPercent(percent + step);
          }
        }, 1000);
      } else {
        setPercent(0);
      }
    }
    updateProgress();
  }, [percent, willReset]);

  return (
    <div className="App">
      <button
        onClick={() => {
          setWillReset(true);
        }}
      >
        Reset
      </button>
      {percent !== 100 && <ProgressBar value={percent} />}
    </div>
  );
}

【问题讨论】:

  • 我将您的代码放在沙箱中,没有任何修改及其工作。 Iink
  • 当进度不是 100% 时,您可以尝试禁用按钮,这也是 google 表单示例
  • 为什么不将百分比设置为 100 而不是 percent + (100 - percent)?

标签: javascript reactjs react-hooks


【解决方案1】:

发生这种情况的原因是因为您在 useEffect 挂钩内部使用了 setTimeout。您必须从您的useEffect 回调中返回一个清理函数来清除setTimeout,否则它将继续被调用。

我会这样写:

useEffect(() => {
  if (willReset) {
    setPercent(0);
    return;
  }

  const id = setTimeout(() => {
    if (percent + step > 100) {
      setPercent(percent + (100 - percent));
    } else {
      setPercent(percent + step);
    }
  }, 1000);

  return () => clearTimeout(id);
}, [percent, willReset]);

【讨论】:

  • 非常感谢,我开始感到沮丧
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-06
  • 2023-01-31
  • 2019-01-09
  • 1970-01-01
  • 2020-03-06
  • 2014-03-09
相关资源
最近更新 更多