Ya implementé una función de desplazamiento infinito en mi aplicación de recetas usando la API de Edamam, pero tengo este problema:
Cuando llego al final de la página y comienza a buscar la página siguiente, el componente realiza una actualización total, muestra todos los elementos de cada página después de eso.
Lo que quiero es que cuando llegue al final, comience a buscar (mostrando mi rueda giratoria en la parte inferior y demás) y muestre la siguiente página en la parte inferior sin actualizar toda la página.
Aquí está mi código:
const RecipesGrid = ({ query }) => { const getRecipes = async (pageParam) => { try { const path = pageParam ? pageParam : `https://api.edamam.com/api/recipes/v2?q=${query}&app_id=${process.env.REACT_APP_APP_ID}&app_key=${process.env.REACT_APP_API_KEY}&type=public`; const response = await axios.get(path); return response.data; } catch (error) { console.log(error); } }; useEffect(() => { const onScroll = (event) => { const { scrollHeight, scrollTop, clientHeight } = event.target.scrollingElement; if (scrollHeight - scrollTop <= clientHeight * 1.2) { fetchNextPage(); } }; document.addEventListener("scroll", onScroll); return () => document.removeEventListener("scroll", onScroll); // eslint-disable-next-line }, []); const { data, isFetching, isFetchingNextPage, status, hasNextPage, fetchNextPage, } = useInfiniteQuery( ["recipes", query], ({ pageParam = "" }) => getRecipes(pageParam), { getNextPageParam: (lastPage) => lastPage._links.next ? lastPage._links.next.href : undefined, } ); if (isFetching || status === "loading") { return <Spinner />; } if (status === "error") { return <div>Whoops! something went wrong...Please, try again</div>; } return ( <div className={styles.Recipes}> {data?.pages.map((item, index) => ( <React.Fragment key={index}> {item.hits.map((recipe) => ( <Recipe recipe={recipe} key={recipe.recipe.uri} /> ))} {item.hits.length === 0 ? ( <Empty message="No results found!" /> ) : null} {!hasNextPage && item.hits.length !== 0 && ( <Empty message="No more recipes!" /> )} </React.Fragment> ))} {isFetchingNextPage && <Spinner />} </div> ); }; export default RecipesGrid;Creo que está desmontando toda la lista porque aquí solo representa una rueda de carga:
if (isFetching || status === "loading") { return <Spinner />; } isFething siempre es verdadero cuando una solicitud está en curso. Esto también es cierto cuando busca la página siguiente, por lo que ingresa a este retorno anticipado y elimina su lista. Eliminar isFetching de la declaración if debería resolverlo, ya que muestra un indicador de carga en segundo plano de todos modos a través de:
{isFetchingNextPage && <Spinner />}Además, su manejo de errores no funcionará porque transforma los errores en promesas resueltas al capturarlos para iniciar sesión y no volver a lanzarlos:
} catch (error) { console.log(error); } Utilice la devolución de llamada onError para cosas como esa.