es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cómo obtener setInterval en React para cambiar una variable de estado?

Quiero que el siguiente código comience a contar hacia atrás desde un número después de que un usuario inicie sesión.

El siguiente código muestra simplemente el número 0 en la consola cada segundo, pero no parece establecer la variable de estado “secondsLeft” en 8, ni contar hacia abajo esta variable.

const [secondsLeft, setSecondsLeft] = useState(0);

const handleButton = async () => {
    const response = await fetch('http://localhost:5001/login', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ username, password })
    });
    setUsername('');
    setPassword('');
    if (response.ok) {
        const data = await response.json();
        setCurrentUser(prev => ({ ...prev, ...data.user }));
        setMessage(`User: ${currentUser.firstName}`);
        setSecondsLeft(8);
        setInterval(() => {
            setSecondsLeft(prev => secondsLeft -1);
            console.log(secondsLeft);
        }, 1000);
    } else {
        setMessage('inicio de sesión incorrecto');
    }
}

¿Cómo puedo hacer que setInterval disminuya el valor de “secondsLeft” cada segundo?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    El problema con el código actual es que está creando una nueva función setInterval cada vez que se llama a la función handleButton. En cambio, deberíamos crear el setInterval solo una vez y usar la función clearInterval para detenerlo cuando termine la cuenta regresiva. Aquí hay una versión actualizada del código:

    const [secondsLeft, setSecondsLeft] = useState(0);
    const [intervalId, setIntervalId] = useState(null);
    
    ...
    
    const handleButton = async () => {
      const response = await fetch('http://localhost:5001/login', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ username, password })
      });
      setUsername('');
      setPassword('');
      if (response.ok) {
        const data = await response.json();
        setCurrentUser(prev => ({ ...prev, ...data.user }));
        setMessage(`Usuario: ${currentUser.firstName}`);
        setSecondsLeft(8);
        const id = setInterval(() => {
          setSecondsLeft(prev => prev - 1);
        }, 1000);
        setIntervalId(id);
      } else {
        setMessage('Inicio de sesión incorrecto');
      }
    }
    
    ...
    
    useEffect(() => {
      if (secondsLeft === 0) {
        clearInterval(intervalId);
      }
    }, [secondsLeft, intervalId]);
    

    Hemos agregado una nueva variable de estado intervalId para almacenar el ID de la función setInterval, que establecemos una vez cuando se hace clic en el botón. Luego, usamos este ID para posteriormente utilizar clearInterval.

    También hemos agregado un gancho useEffect para verificar si secondsLeft ha alcanzado 0 y, en caso afirmativo, detener el setInterval. Ten en cuenta que debemos incluir intervalId en la matriz de dependencias para que se actualice correctamente.

    Con estos cambios, la cuenta regresiva ahora debería funcionar como se esperaba.

Comments are closed.