Estoy tratando de incrementar el valor de React state setMoviesPage en 1 cada vez que se llama handleScroll() . El problema al que me enfrento es que el estado setMoviesPage se actualiza solo el componente se vuelve a procesar (al navegar a una URL diferente y regresar).
Este es mi código:
const [moviesPage, setMoviesPage] = useState(1); async function handleScroll() { if (window.innerHeight + document.documentElement.scrollTop !== document.documentElement.offsetHeight) return; await setIsFetching(true); setMoviesPage(moviesPage + 1); } useEffect(() => { if (!isFetching) return; fetchMovies(String(moviesPage)) .then(prevState => updateMovies([...prevState])) .catch(() => updateMovies([])); setIsFetching(false); }, [isFetching, setIsFetching, moviesPage, updateMovies]);¿Como arreglarlo? Gracias
Cuando busqué su código por primera vez, lo que realmente quiero decirle es que su useEffect parece no estar en las mejores prácticas utilizadas.
Aquí lo modifico para ti con mejor estructura.
const fetchMovie = () => { setIsFetching(true) fetchMovies(String(moviesPage)) .then(prevState => updateMovies([...prevState])) .catch(() => updateMovies([])); setIsFetching(false) } useEffect(() => { fetchMovie }, [moviesPage]);Y tenga en cuenta que solo necesita agregar la matriz de dependencias para usarEfecto todo el valor cambiado que activará su acción dentro de él. Además, a veces linter puede darte una advertencia de falso positivo.
Espero que esta respuesta pueda ayudarte a resolver tu problema.
Parece que cuando se completa la búsqueda de películas, simplemente sobrescribe el estado existente.
fetchMovies(String(moviesPage)) .then(prevState => updateMovies([...prevState])) // <-- overwrite state .catch(() => updateMovies([])); Con los componentes de función y el useState , las actualizaciones de estado no se fusionan con el estado existente, debe administrar esto manualmente.
Nota
A diferencia del método
setStateque se encuentra en los componentes de clase,useStateno fusiona automáticamente los objetos de actualización. Puede replicar este comportamiento combinando el formulario de actualización de funciones con la sintaxis de distribución de objetos:const [state, setState] = useState({}); setState(prevState => { // Object.assign would also work return {...prevState, ...updatedValues}; });
Actualice el valor de moviesPage en el controlador de desplazamiento
function handleScroll() { if (window.innerHeight + document.documentElement.scrollTop !== document.documentElement.offsetHeight) return; setMoviesPage(moviesPage + 1); }Factorice la lógica de obtención en una función de utilidad. Use una actualización de estado funcional para actualizar desde el estado anterior, agregando los nuevos datos a una nueva referencia de matriz. Mueva el restablecimiento del estado de carga a la cadena Promise para que se restablezca correctamente al final de la cadena; de lo contrario, simplemente cancelaría la actualización verdadera de inicio de carga.
const fetchNextMoviesPage = (page) => { if (!isFetching) { setIsFetching(true); // <-- start loading fetchMovies(String(page)) .then(nextPage => { updateMovies(movies => movies.concat(nextPage)); // <-- append next page }) .catch(() => updateMovies([])) .finally(() => setIsFetching(false)); // <-- end loading } }; useEffect(() => { fetchNextMoviesPage(moviesPage); }, [moviesPage]);