Tengo el siguiente problema con el gancho useInterval, estoy tratando de hacer que el contador se detenga si llega a la cuenta 20, pero parece que la forma en que lo estoy implementando actualmente parece causar un bucle infinito de renderizado. Aquí está mi código hasta ahora:
import React, { ChangeEvent, useState } from "react"; import { useInterval } from "usehooks-ts"; export default function Component() { // The counter const [count, setCount] = useState<number>(0); // Dynamic delay const [delay, setDelay] = useState<number>(1000); // ON/OFF const [isPlaying, setPlaying] = useState<boolean>(true); useInterval( () => { // Your custom logic here setCount(count + 1); }, // Delay in milliseconds or null to stop it isPlaying ? delay : null ); if (count === 10) { setPlaying(false); } const handleChange = (event: ChangeEvent<HTMLInputElement>) => { setDelay(Number(event.target.value)); }; return ( <> <h1>{count}</h1> <button onClick={() => setPlaying(!isPlaying)}> {isPlaying ? "pause" : "play"} </button> <p> <label htmlFor="delay">Delay: </label> <input type="number" name="delay" onChange={handleChange} value={delay} /> </p> </> ); }No puedo entender por qué esto no funciona, ¿podría alguien explicarme y mostrarme qué estoy haciendo mal?
El siguiente bloque en el código es lo que está causando el ciclo infinito, ya que en cada procesamiento después de que el conteo sea 10 y el contador esté en pausa, setPlaying(false) se ejecutará cada vez y hará que se vuelva a procesar cada vez, lo que provocará el ciclo infinito.
if (count === 10) { setPlaying(false); }En su lugar, puede mover este bloque a un efecto de uso como
useEffect(() => { if (count === 10) { setPlaying(false); } }, [count]);Encuentre códigos y caja para referencia
cada estado de actualización o props hace que se cree un nuevo intervalo.
Si tienes que usar el intervalo
let myinterval = useInterval( () => { // Your custom logic here setCount(count + 1); }, // Delay in milliseconds or null to stop it isPlaying ? delay : null ); clearInterval(myinterval);pones este código en useEffect
useEffect(()=>{ if(count <20){ let myinterval = useInterval( () => { // Your custom logic here setCount(count + 1); }, // Delay in milliseconds or null to stop it isPlaying ? delay : null ); clearInterval(myinterval); } },[count])Con un gancho useEffect :
useEffect(() => { if (count === 10) { setPlaying(false); } }, [count])Cada vez que cambie el conteo, useEffect se activará y verificará si el conteo ha llegado a 10.
También puede evitar que el usuario cambie de estado por encima de 10:
<button onClick={() => setPlaying(count === 10 ? false : !isPlaying)}>