切换标签时反应倒数圈计时器重置

时间:2021-03-30 11:02:21

标签: javascript reactjs timer react-hooks

在我的项目中,我使用的是 React Countdown Clock Timer NPM 包。我有两个这样的计时器同时出现,一个分钟计时器和一个秒计时器。一切正常,除了当我切换标签时,我的分钟保持正确的分钟数,而我的秒计时器重置。我希望秒计时器即使在我切换标签时也能保持正确的设置数量。

这是我当前的 iies 计时器文件

import React, { useState, useContext } from "react";
import { CountdownCircleTimer } from "react-countdown-circle-timer";
import { AuthContext } from "../../context/Auth";
import { ChillContext } from "../../context/ChillContext";
import { db } from "../../services/firebase";
import firebase from "firebase/app";
import chime from "../../sounds/chime.mp3";
import {
  CountdownTimerWrapper,
  CountdownTimerMain,
  TimersWrapper,
  RestartButton,
  StartStopButton,
  ButtonsWrapper,
  TimerCheck,
  TimerHeading,
  TimerControl,
  TimerText,
} from "./CountdownTimerElements";
import Toggle from "../Toggle/Toggle";
import { Howl } from "howler";

const minuteSeconds = 60;
const hourSeconds = 3600;

const renderTime = (dimension, time) => {
  return (
    <div className="time-wrapper">
      <div className="time">{time}</div>
      <div>{dimension}</div>
    </div>
  );
};

const getTimeSeconds = (time) => (minuteSeconds - time) | 0;
const getTimeMinutes = (time) => ((time % hourSeconds) / minuteSeconds) | 0;

const CountdownTimer = () => {
  const stratTime = Date.now() / 1000; // use UNIX timestamp in seconds
  const workEndTime = stratTime + 25 * 60; // use UNIX timestamp in seconds
  const chillEndTime = stratTime + 5 * 60;
  const [minutesKey, setMinutesKey] = useState(0);
  const [secondsKey, setSecondsKey] = useState(10);
  const [playing, setPlaying] = useState(false);
  const [timerButtonDesc, setTimerButtonDesc] = useState("Start");
  const { currentUser } = useContext(AuthContext);
  const { chill, setChill } = useContext(ChillContext);
  const chillRemainingTime = chillEndTime - stratTime;
  const workRemainingTime = workEndTime - stratTime;

  const timerProps = {
    isPlaying: playing,
    size: 100,
    strokeWidth: 6,
  };

  const sound = new Howl({
    src: [chime],
  });

  return (
    <CountdownTimerWrapper>
      <CountdownTimerMain>
        <TimerHeading>Pomodoro Timer</TimerHeading>
        {chill ? (
          <TimersWrapper>
            <CountdownCircleTimer
              {...timerProps}
              colors={[["#9294e3"]]}
              key={minutesKey}
              duration={hourSeconds}
              initialRemainingTime={chillRemainingTime % hourSeconds}
              onComplete={(totalElapsedTime) => {
                return [chillRemainingTime - totalElapsedTime > minuteSeconds];
              }}
            >
              {({ elapsedTime }) =>
                renderTime("minutes", getTimeMinutes(hourSeconds - elapsedTime))
              }
            </CountdownCircleTimer>
            <TimerControl>
              <Toggle
                onChange={(event) => {
                  setChill(event.target.checked);
                  setSecondsKey((prevKey) => prevKey + 1);
                  setMinutesKey((prevKey) => prevKey + 1);
                  setTimerButtonDesc("Start");
                  setPlaying(false);
                }}
              />
              <TimerText>{chill ? "Chill" : "Work"} Timer </TimerText>
            </TimerControl>
            <CountdownCircleTimer
              {...timerProps}
              colors={[["#9294e3"]]}
              key={secondsKey}
              duration={minuteSeconds}
              initialRemainingTime={chillRemainingTime % minuteSeconds}
              onComplete={(totalElapsedTime) => {
                console.log(totalElapsedTime - chillRemainingTime);
                if (totalElapsedTime - chillRemainingTime === 0) {
                  return false;
                }
                return [chillRemainingTime - totalElapsedTime > 0];
              }}
            >
              {({ elapsedTime }) =>
                renderTime("seconds", getTimeSeconds(elapsedTime))
              }
            </CountdownCircleTimer>
          </TimersWrapper>
        ) : (
          <TimersWrapper>
            <CountdownCircleTimer
              {...timerProps}
              colors={[["#d87463"]]}
              key={minutesKey}
              duration={hourSeconds}
              initialRemainingTime={workRemainingTime % hourSeconds}
              onComplete={(totalElapsedTime) => {
                return [workRemainingTime - totalElapsedTime > minuteSeconds];
              }}
            >
              {({ elapsedTime }) =>
                renderTime("minutes", getTimeMinutes(hourSeconds - elapsedTime))
              }
            </CountdownCircleTimer>
            <TimerControl>
              <Toggle
                onChange={(event) => {
                  setChill(event.target.checked);
                  setSecondsKey((prevKey) => prevKey + 1);
                  setMinutesKey((prevKey) => prevKey + 1);
                  setTimerButtonDesc("Start");
                  setPlaying(false);
                }}
              />
              <TimerText>{chill ? "Chill" : "Work"} Timer </TimerText>
            </TimerControl>
            <CountdownCircleTimer
              {...timerProps}
              colors={[["#d87463"]]}
              key={secondsKey}
              duration={minuteSeconds}
              initialRemainingTime={workRemainingTime % minuteSeconds}
              onComplete={(totalElapsedTime) => {
                if (totalElapsedTime - workRemainingTime === 0) {
                  db.collection("emails")
                    .doc(currentUser.email)
                    .update({
                      pomodoros: firebase.firestore.FieldValue.increment(1),
                    });

                  sound.play();
                }
                return [workRemainingTime - totalElapsedTime > 0];
              }}
            >
              {({ elapsedTime }) =>
                renderTime("seconds", getTimeSeconds(elapsedTime))
              }
            </CountdownCircleTimer>
          </TimersWrapper>
        )}
        <ButtonsWrapper>
          <RestartButton
            onClick={() => {
              setSecondsKey((prevKey) => prevKey + 1);
              setMinutesKey((prevKey) => prevKey + 1);
              setPlaying(false);
              setTimerButtonDesc("Start");
            }}
          >
            Restart Timer
          </RestartButton>
          <TimerCheck />

          <StartStopButton
            onClick={() => {
              if (timerButtonDesc === "Start") {
                setTimerButtonDesc("Stop");
              } else {
                setTimerButtonDesc("Start");
              }
              setPlaying(!playing);
            }}
          >
            {timerButtonDesc}
          </StartStopButton>
        </ButtonsWrapper>
      </CountdownTimerMain>
    </CountdownTimerWrapper>
  );
};

export default CountdownTimer;

1 个答案:

答案 0 :(得分:0)

您遇到的问题是您将“key”设置为minutesKey。 每次更改“键”时,计时器都会重置。如果reset 不是folw 的一部分,您希望传入一个常量。如果重置是流程的一部分,则为其设置一个单独的状态。

 <CountdownCircleTimer
          {...timerProps}
          colors={[["#d87463"]]}
          key={0}
          duration={minuteSeconds}
          initialRemainingTime={workRemainingTime % minuteSeconds}
          onComplete={(totalElapsedTime) => {
            if (totalElapsedTime - workRemainingTime === 0) {
              db.collection("emails")
                .doc(currentUser.email)
                .update({
                  pomodoros: firebase.firestore.FieldValue.increment(1),
                });

              sound.play();
            }
            return [workRemainingTime - totalElapsedTime > 0];
          }}
        >
          {({ elapsedTime }) =>
            renderTime("seconds", getTimeSeconds(elapsedTime))
          }
        </CountdownCircleTimer>
相关问题