Quiero incrementar la cantidad de usuarios después de cada 200 ms hasta 5000 con el siguiente código. Pero no borra el intervalo cuando el número de usuarios es superior a 5000.
const Cards = () => { const [users, setUsers] = useState(40); useEffect(() => { const setIntervalUsers = setInterval(() => { setUsers((prevUsers) => prevUsers = prevUsers + 100) }, 200); if (users >= 5000) { console.log('ok'); clearInterval(setIntervalUsers) } }, []); return (<div>number of users {users} </div>)}Le sugiero que devuelva una función de limpieza para que no registre el intervalo dos veces en caso de que esté en StrictMode con React 18, y también para eliminarlo de la memoria cuando se desmonte el componente.
También use un conjunto de ref con useRef y un useEffect separado que vería los cambios en users y borraría el intervalo allí. Al igual que:
import { useEffect, useRef, useState } from "react"; const Cards = () => { const [users, setUsers] = useState(40); const intervalRef = useRef(); useEffect(() => { if (users >= 5000) { console.log("ok"); clearInterval(intervalRef.current); } }, [users]); useEffect(() => { intervalRef.current = setInterval(() => { setUsers((prevUsers) => (prevUsers = prevUsers + 100)); }, 200); return () => clearInterval(intervalRef.current); }, []); return <div>number of users {users} </div>; };La forma en que verifica su condición de users >= 5000 no funciona porque users no figuran como una dependencia en su useEffect . Por lo tanto, el gancho solo se ejecuta una vez, pero no se vuelve a ejecutar cuando cambian users . Debido a eso, solo verifica 40 >= 5000 una vez al principio.
Una forma más fácil de manejar eso es sin una forma setInterval .
export const Cards = () => { const [users, setUsers] = useState(40); useEffect(() => { // your break condition if (users >= 5000) return; const increment = async () => { // your interval await new Promise((resolve) => setTimeout(resolve, 200)); setUsers((prevState) => prevState + 100); } // call your callback increment(); // make the function run when users change. }, [users]); return <p>current number of users {users}</p> }Esto no funciona porque:
Hice una muestra funcional de su código aquí: https://codepen.io/aSH-uncover/pen/wvmYdNy
Además, debe limpiar el intervalo cuando se destruye el componente devolviendo la llamada cleanInterval en el gancho que creó el intervalo.
const Card = ({ step }) => { const intervals = useRef({}) const [users, setUsers] = useState(40) useEffect(() => { intervals.users = setInterval(() => { setUsers((prevUsers) => prevUsers = prevUsers + step) }, 200) return () => clearInterval(intervals.users) }, []) useEffect(() => { if (users >= 5000) { clearInterval(intervals.users) } }, [users]) return (<div>number of users {users} </div>) }