通过单击 ReactJs 中的按钮重置 LinearProgress 倒计时

Reset LinearProgress countdown by click on the button in ReactJs

简介:在我的reactjs应用程序部分,输入手机号码后,会向用户发送一个密码,然后modal 已打开,用户应输入密码。在此模式中,有一个 countdown 呈现 progress-bar 等待时间。

问题:完成进度后(例如,用户未输入 PIN 码或未收到消息),出现重新发送按钮,如果用户单击,此进度应该被重置。

问题:如何通过点击按钮重置progress-bar?或者如何用初始状态重置组件?

代码:CounterProgress

import React, { useEffect, useState } from 'react'
import Countdown from "react-countdown";
import { Button, LinearProgress,} from "@material-ui/core";


function CounterProgress() {

    const waitingTime = 10000;
    const [counterRemained, setCounterRemained] = useState(waitingTime);
    const [currentTime, setCurrentTime] = useState(Date.now() + counterRemained);
    const [resend, setResend] = useState(true);


    const counterRenderer = ({ minutes, seconds, completed, total }) => {
        setCounterRemained(total)
        const mainMin = waitingTime;
        const onePercent = mainMin / 100;
        const leftedPercent = total / onePercent;
        
        return (
            resend ? (
                <>
                    <LinearProgress
                        variant="determinate"
                        value={leftedPercent}
                        dir="ltr"
                        style={{ height: "0.7rem", borderRadius: "10px" }}
                        className={` w-75 mx-auto`}
                    />
                    <div style={{
                        display: "block",
                        marginLeft: "auto",
                        marginRight: "auto",
                    }}>
                        <Button
                            disabled={true}
                            style={counterRemained === 0 ? { textColor: "#6dd06d" } : {}}
                        >
                            resend code
                        </Button>
                        <span style={{ textColor: "black", fontSize: "10px" }}>{minutes}:{seconds}</span>
                    </div>
                </>

            ) : (
                <>
                    <Button
                        style={counterRemained === 0 ? { textColor: "#6dd06d" } : {}}
                        onClick={() => setResend(true)}

                    >
                        resend code
                    </Button>
                </>
            )

        );

    };   

    return (
        <Countdown
            date={currentTime}
            renderer={counterRenderer}
            onComplete={() => {
                setResend(false);
            }}
        />
    );
}

export default CounterProgress;

此代码在用户单击按钮时有效,但 progress-bar 未重置且不起作用。

我的解决方案不起作用:

  1. 使用 重置 CounterProgress 组件。
  2. countdown 中使用 key 选项。此方法自动运行,无需 onClick.

使用密钥选项:

const [times, setTimes] = useState([Date.now() + waitingTime, Date.now() + 2 * waitingTime]);
const [currentTimeIndex, setCurrentTimeIndex] = useState(0);

return (
    <Countdown
        date={currentTime}
        key={currentTimeIndex}
        renderer={counterRenderer}
        onComplete={() => {
            console.log("completed", currentTimeIndex)
            if (times.length - 1 <= times.indexOf(currentTime)) return;
            setCurrentTimeIndex(currentTimeIndex + 1);
            setCurrentTime(new Date(times[currentTimeIndex + 1]));
        }}
    />
);

好的,您可以使用useEffect hook在进度条结束时重新发送代码。

您可以将 resend 作为 useEffect 的依赖项,这样每当 resend 的值更新或更改时 useEffect 都会被调用。

示例:

 useEffect(() => {
    //reset your state to initial state.
 }, [resend])

我为 countdown 使用了 key 选项。我将重新发送状态作为状态三个值(-1、0、1)。

修改的部分代码:

const waitingTime = 120000;

const [counterRemained, setCounterRemained] = useState(waitingTime);
const [times, setTimes] = useState([Date.now() + waitingTime, Date.now() + 2 * waitingTime]);
const [currentTime, setCurrentTime] = useState(Date.now() + counterRemained);
const [currentTimeIndex, setCurrentTimeIndex] = useState(0);
const [resend, setResend] = useState(-1);



useEffect(() => {
    // resend sms to user
    if (resend === 0) { // by clicking on the button, resend be 0
        setResend(-1) // for initializing
        setCurrentTimeIndex(currentTimeIndex + 1);
        setCurrentTime(new Date(times[currentTimeIndex + 1]));
    }

}, [resend])

return (
    <>
        <Countdown
            date={currentTime}
            key={currentTimeIndex}
            renderer={counterRenderer}
            onComplete={() => {
                if (times.length - 1 <= times.indexOf(currentTime)) return;
            }}
        />
    </>
);