Resultado deseado: Obtengo el estado de un script de una API y luego verifico cuál es el estado. Si el estado = 'XYZ', necesito volver a llamar a la función getStatus (usando setInterval), de lo contrario, solo necesito regresar/no hacer nada.
Problema: El principal problema es que clearInterval() no funciona y se llama a la función getStatus() después del intervalo mencionado (10 segundos aquí) una y otra vez, AUNQUE el estado NO ES IGUAL a 'XYZ'.
Por favor ayuda Gracias por adelantado.
const [intervalId, setIntervalId] = useState(); useEffect(() => { getStatus(); }, []); const getStatus = async () => { await getScriptStatus()() .then(response => { if (response.data[0].status == 'XYZ') { setIntervalId( setInterval(() => { getStatus(); }, 10000) ); } else return () => clearInterval(intervalId); }) .catch(error => { errorMessage(error); });ACTUALIZAR: Usar React.useRef() en lugar de useState() para intervalId y borrar el intervalo antes de usar setInterval() en la condición 'si' funcionó o yo. Gracias por las respuestas útiles.
Use setTimeout en lugar de usar setInterval .
Para obtener más detalles, visite: Documentación sobre setTimeout
El problema principal aquí es probablemente que está instalando nuevos intervalos de forma recursiva : la función instala el intervalo que llama a la función que instala el intervalo, etc., produciendo efectivamente una cascada de intervalos. Estos son más o menos revocables, porque sus identificaciones viven efímeramente en el alcance de la función que los instaló y luego se desechan.
Puede observarlo con una versión ligeramente modificada de su código en este sandbox .
intervalId no necesita ser un "estado", sino que la tienda es como una referencia y no como un estado.
.then().catch() a usar async/await .setIntervalId aún no actualizó el intervalId , cuando intenta acceder al nuevo valor de intervalId const intervalId = useRef(null); const getStatus = async () => { try { const response = await getScriptStatus()() if (response.data[0].status == 'XYZ') { intervalId.current = setInterval(getStatus, 10000); } else return () => clearInterval(intervalId.current); } catch (error) { errorMessage(error); } }Otra sugerencia:
La función getStatus no debería actuar como una función useEffect, porque es muy confuso ver que getStatus devuelve una función... y luego debe volver a "AH, es una función useEffect... y la función devuelta es una función de limpieza .. " - no es bueno.. .
así que... Mis opciones sugeridas para eso:
getState a solo getStatus ... y luego, cuando la llame desde dentro de useEffect , también maneje el caso en el que desea devolver una función (función de limpieza)useEffect . Y dado que desea usar async/await -> cree una función asíncrona autollamada: useEffect(()=>{ (async () => { await func(); })(); }, []); Además de todo eso ^ Realmente no necesitas el setInterval (como otros han sugerido). setTimeout bien. Pero es posible que aún desee clearTimeout (cambiado de clearInterval) si la función se puede llamar en diferentes ocasiones