En esta ocasión vamos a implementar un scroll infinito usando React JS.
Una aplicación que implementa scroll infinito consiste en un diseño que permite a los usuarios seguir consumiendo cierta cantidad de información sin ninguna pausa, ya que el contenido se va cargando automáticamente conforme el usuario vaya haciendo scroll.
🚨 Nota: Este post requiere que sepas las bases de React con TypeScript (hooks básicos).
Cualquier tipo de Feedback es bienvenido, gracias y espero disfrutes el articulo.🤗
🚨 Nota: La interfaz Result en realidad tiene mas propiedades pero en este caso solo usare las que he definido.
🎈 Haciendo la petición a la API.
En este caso usaremos la librería React Query que nos va a permitir realizar las peticiones de una mejor forma (y que ademas cuenta con otras características como manejo de caché)
Instalamos la dependencia
```
npm i @tanstack/react-query
Y luego en el archivo `src/main.tsx` vamos hacer lo siguiente:
Vamos a encerrar nuestro componente **App** dentro del **QueryClientProvider** y le mandamos el cliente que es solamente una nueva instancia de **QueryClient**.
```tsx
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import './index.css'
const queryClient = new QueryClient()
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
<React.StrictMode>
<QueryClientProvider client={queryClient}>
<App />
</QueryClientProvider>
</React.StrictMode>
)
Ahora en el archivo src/App.tsx, vamos a usar un hook especial de React Query llamado useInfiniteQuery
El hook useInfiniteQuery necesita varios parámetros:
1 - queryKey: un arreglo de strings u objetos anidados, que se usa como clave para gestionar el almacenamiento del cache.
2 - queryFn: Una función que devuelve una promesa, la promesa debe estar resuelta o lanzar un error.
3 - options: Dentro de las opciones necesitamos una que se llama getNextPageParam que es una función que devuelve la información para la siguiente consulta a la API.
El primer parámetro es la queryKey en este caso colocamos un arreglo con la palabra 'characters'
Dicha función debe retornar una promesa resuelta.
Para ello, fuera del componente creamos una función que recibirá como parámetro la pagina a traer y retornara una promesa de tipo ResponseAPI.
La queryFn recibe diversos parámetros, entre ellos el pageParam que por defecto sera undefined y luego numero, asi que si no existe un valor, lo igualaremos a 1. y dicha propiedad se la pasamos a la función fetcher.
La función getNextPageParam recibe dos parámetros pero solo usaremos el primero que es la ultima pagina recibida (o sea la ultima respuesta que nos dio la API).
Dentro de la función, como la API de Rick and Morty no viene ña pagina siguiente (mas bien viene la url para la pagina siguiente) tendremos que realizar lo siguiente:
1 - Obtendremos la pagina anterior
La respuesta de la API viene la propiedad info que contiene la propiedad prev, evaluamos si existe (porque en la primera llamada la propiedad prev es null).
Si no existe entonces es la pagina 0.
Si existe entonces obtenemos esa cadena la separamos y obtenemos el número.
Ahora podemos mostrar los resultados gracias a que ya tenemos acceso a la data.
Creamos un div y dentro vamos a hacer una iteración sobre la propiedad data accediendo a la propiedad page que es un arreglo que por el momento accederemos a la primera posición y a los results.
Ademas evaluamos el status y si es loading mostramos el componente Loading.tsx pero si esta en error, colocamos el mensaje de error.
dataLength: La cantidad de elementos, en un momento le colocaremos el valor ya que necesitamos calcularlo.
next: una función que se disparara cuando se llegue al final de la pagina cuando se haga scroll. Aquí llamaremos a la función que nos ofrece useInfiniteQuery, fetchNextPage.
hasMore: propiedad booleana que indica si hay más elementos. Aquí llamaremos a la propiedad que nos ofrece useInfiniteQuery, hasNextPage, y lo convertimos en booleano con !! porque por defecto es undefined.
loader: componente JSX que se usara para mostrar un mensaje de carga mientras se hace la petición. Aquí llamaremos al componente Loading.tsx
Ahora, la propiedad dataLength podríamos pero esto solo mostraría la pagina siguiente sin acumularse los resultados anteriores, por lo que debemos realizar lo siguiente:
Crearemos una variable memorizada que cambien cada vez que la propiedad data de useInfiniteQuery cambie.
Esta variable characters debe de retornar un nueva ResponseAPI pero el la propiedad de results se deben acumular los personajes anteriores y los actuales. Y la propiedad info sera la de la pagina actual.
Ahora le pasamos esta constante a dataLength, hacemos una evaluación si existe los personajes entonces colocamos la longitud de la propiedad results sino colocamos 0.
Todo el proceso que acabo de mostrar, es una de las formas en que se puede implementar scroll infinito de una manera rápida usando paquetes de terceros. ♾️
Espero haberte ayudado a entender como realizar este diseño,muchas gracias por llegar hasta aquí! 🤗❤️
Te invito a que comentes si es que este articulo te resulta útil o interesante, o si es que conoces alguna otra forma distinta o mejor de como implementar un scroll infinito. 🙌