Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

141
Vistas
onClick decreases the number with each click rather than starting the timer

So I'm building a meditation app in React. To start out simple I gave it a 25 minute countdown.

I want the countdown to start when the button is clicked. However, when I wrap the setInterval in the handleClick() function the seconds go down per click rather than triggering the countdown once.

Any help is appreciated, thanks in advance.

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


function Timer() {
  const [minutes, setMinutes] = useState(25);
  const [seconds, setSeconds] = useState(0);

  function handleClick() {
    console.log('Clicked');
    let interval = setInterval(() => {
      clearInterval(interval);
      if (seconds === 0) {
        if (minutes !== 0) {
          setSeconds(59);
          setMinutes(minutes - 1);
      } else {
        setSeconds(seconds - 1);
      }
    }, 1000)
  }

  const timerMinutes = minutes < 10 ? `0${minutes}`: minutes;
  const timerSeconds = seconds < 10 ? `0${seconds}` : seconds;

  return (
    <>
      <div className="grey-box">
        <div className="number-box">
          <h2 className="timer-text">{timerMinutes}:{timerSeconds}</h2>
        </div>
        <div className="buttons-container">
          <button className="timer-button" onClick={handleClick}>
            <img 
              className="play" 
              src="https://img.icons8.com/ios-glyphs/90/ffffff/play--v1.png" 
            />
          </button>
        </div>
      </div>
    </>
    );
  }

export default Timer;
about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

You are declaring with each click that a minute is subtracted:

setMinutes(minutes - 1);

If you want the timer to only be set once, you can check to see if it has already been set, and if so, abort the handleClick function. A let declaration for the timer will only be available in that block of code (per run). So when another click happens, you won't have access to the timer. Use "this.interval" (function scope) or "var interval" (global/window scope) and then you will be able to check at the top of the handleClick function if the timer is already set.

if (this.interval) return;

OR

if (interval) return;

about 4 years ago · Juan Pablo Isaza Denunciar

0

You're creating the Timer in a much more complicated manner. I made a sample that can cover this use case along with some edge cases.

Codesandbox link

import React, { useState, useEffect, useRef } from "react";
import ReactDOM from "react-dom";
import "./styles.css";

function ClearTimer(TimerHndlRef) {
    clearInterval(TimerHndlRef.current);
    TimerHndlRef.current = null;
}
function App() {
    const TimerHndlRef = useRef();
    const [seconds, secondsSet] = useState(5);
    const onClick = () => {
        if (TimerHndlRef.current) {
            ClearTimer(TimerHndlRef);
            return;
        }
        TimerHndlRef.current = setInterval(
            () =>
                secondsSet((s) => {
                    const v = s - 1;
                    if (v > 0) return v;
                    ClearTimer(TimerHndlRef);
                    return 0;
                }),
            1000,
        );
    };
    const onChange = (e) => secondsSet(parseInt(e.target.value, 10));
    useEffect(() => {
        return () => {
            if (!TimerHndlRef.current) return;
            ClearTimer(TimerHndlRef);
        };
    }, []);
    const mLeft = Math.floor(seconds / 60);
    const sLeft = seconds - mLeft * 60;
    const mDisp = mLeft < 10 ? `0${mLeft}` : mLeft;
    const sDisp = sLeft < 10 ? `0${sLeft}` : sLeft;
    return (
        <div>
            <p>
                <input type="number" value={seconds} onChange={onChange} /> = {mDisp}m +{" "}
                {sDisp}s
            </p>
            <button onClick={onClick}>Test</button>
        </div>
    );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda