Tengo el siguiente fragmento de código. ¿Por qué mi límite siempre es 0 en mi fetchData ? Si fuera a console.log(limit) fuera de esta función, tiene el número correcto. Además, si no uso useState sino una variable let limit = 0; entonces funciona como se esperaba
También agregué limit como una dependencia en useEffect pero sigue activando la función
const [currentData, setData] = useState([]); const [limit, setLimit] = useState(0); const fetchData = async () => { console.log(limit); const { data } = await axios.post(endpoint, { limit: limit, }); setData((state) => [...state, ...data]); setLimit((limit) => limit + 50); }; useEffect(() => { fetchData(); window.addEventListener(`scroll`, (e) => { if (bottomOfPage) { fetchData(); } }); }, []);Cuando pasa una matriz de dependencia vacía [] a useEffect , el efecto se ejecuta solo una vez en el renderizado inicial :
Si pasa una matriz vacía ([]), los accesorios y el estado dentro del efecto siempre tendrán sus valores iniciales.
Si desea ejecutar un efecto y limpiarlo solo una vez (al montar y desmontar), puede pasar una matriz vacía ([]) como segundo argumento. Esto le dice a React que su efecto no depende de ningún valor de accesorios o estado, por lo que nunca necesita volver a ejecutarse. Esto no se maneja como un caso especial: se deriva directamente de cómo funciona siempre la matriz de dependencias.
El estado inicial de limit es 0 como se define en su llamada useState . Agregar limit como una dependencia hará que el efecto se ejecute cada vez que cambie el limit de tiempo.
Una forma de solucionar su problema es envolver el método fetchData en un useCallback mientras pasa la variable de limit a la matriz de dependencia.
A continuación, puede pasar la función a la matriz de dependencias de useEffect y también devolver una función desde dentro de useEffect que elimine los detectores de eventos con referencias obsoletas.
También debe agregar una variable de carga para que la función fetchData no se llame varias veces mientras el usuario se desplaza hacia abajo:
const [currentData, setData] = useState([]); const [limit, setLimit] = useState(0); const [loading, setLoading] = useState(false); const fetchData = useCallback(async () => { console.log(limit); // Prevent multiple endpoint calls when scrolling near the end with a loading state if (loading) { return; } setLoading(true); const { data } = await axios.post(endpoint, { limit }); setData((state) => [...state, ...data]); setLimit((limit) => limit + 50); setLoading(false); }, [limit, loading]); // Make the initial request on the first render only useEffect(() => { fetchData(); }, []); // Whenever the fetchData function changes update the event listener useEffect(() => { const onScroll = (e) => { if (bottomOfPage) { fetchData(); } }; window.addEventListener(`scroll`, onScroll); // On unmount ask it to remove the listener return () => window.removeEventListener("scroll", onScroll); }, [fetchData]);