Saltar al contenido

Cómo implementar el Desplazamiento Infinito con ReactJs

En Reactancia, tenemos dos opciones para desarrollar un pergamino infinito.

  • Usando una biblioteca de terceros
  • Usando un mecanismo de desplazamiento infinito personalizado

Aquí en esta guía, desarrollaremos un sencillo mecanismo de desplazamiento infinito personalizado que nos ayuda a cargar datos basados en un evento de desplazamiento.

Cómo implementar el Desplazamiento Infinito con ReactJs
Cómo implementar el Desplazamiento Infinito con ReactJs

Antes de empezar, necesitamos que los datos se carguen continuamente, por lo que para ello utilizaremos una plataforma de API falsa que nos proporciona los datos falsos utilizando su API oficial. La URL que vamos a utilizar se indica a continuación.

https://jsonplaceholder.typicode.com/photos

Para llamar a la API, deberíamos tener instalado Axios en nuestra aplicación, que se utiliza para hacer una petición HTTP para recuperar o guardar los datos de nuestra aplicación. Es una librería de terceros, por lo que podemos instalarla usando el siguiente comando npm.

1npm instalar axios

powerhell

Vamos a crear un nuevo componente hijo llamado ScrollComponent.jsx y crear un objeto de estado como este.

1234567891011121314151617181920212223importarReaccionar,{Componente}de "reaccionar";importar axios de "axios";classScrollComponenteextiendeComponente{constructor(){super();esto. state={ photos:[], loading:false, page:0, prevY:0};}render(){return(<divclassName="container"</div>);}}exportdefaultScrollComponent;

jsx

En nuestro componente de desplazamiento, hemos creado algunos valores de estado para almacenar las fotos de la respuesta de la API y otros valores de estado para gestionar las propiedades de la página y el comportamiento de carga.

Ahora, tenemos que crear una función que contenga el código fuente utilizado para obtener los datos de la API falsa utilizando el paquete Axios. Vamos a crear la función reutilizable de esta manera.

1234567891011getPhotos(page){this.setState({ loading:true}); axios .get(`https://jsonplaceholder.typicode.com/photos?_page=${page}&_limit=10`).then(res=>{this.setState({ photos:[...this.state.photos,...res.data]});this.setState({ loading:false});}

jsx

En esta función, hemos establecido el valor del estado de carga en true, lo que denota que los datos se están cargando desde la API. Hemos utilizado Axios junto con la URL de la API, que recupera los datos del servidor.

Después de obtener la respuesta basada en la solicitud, necesitamos almacenar los datos en un conjunto separado llamado fotos que hemos creado anteriormente en este componente.

Si te das cuenta, hemos combinado los datos anteriores y los actuales, sólo porque llamaremos a esta función continuamente basada en el evento de desplazamiento, y añadirá la respuesta en el conjunto de fotos.

Después de crear la función, tenemos que llamarla una vez que el componente se ha cargado, por lo que podemos llamarla desde la función componenteDidMount () de esta manera.

123componentDidMount(){this.getPhotos(this.state.page);}

jsx

Hemos configurado la función básica de la API desde donde llamaremos a la API. También hemos llamado a la función getPhotos() desde el gancho de ciclo de vida del componenteDidMount(), pero será suficiente para desarrollar el scroll infinito.

Ahora, tenemos que escuchar el comportamiento de cada evento de desplazamiento, y en base al evento de desplazamiento, el número de página se actualizará para obtener los nuevos datos de la API.

Usaremos el observador de intersección, que hace dos cosas:

  • Describe la API utilizada para obtener la posición del elemento DOM del elemento objetivo.
  • Obtiene el estado de pre-carga y aplazamiento del elemento del contenido del DOM.

Vamos a actualizar el componenteDidMount() ganchos como este.

123456789101112131415componentDidMount(){this.getPhotos(this.state.page);var options ={ root:null, rootMargin: "0px", threshold:1.0};this.observer=newIntersectionObserver(this.handleObserver.bind(this), options );this.observer.observe(this.loadingRef);}

jsx

En esta función de gancho, hemos creado algunas opciones:

  • raíz: Esta es la raíz a utilizar para la intersección.
  • rootMargin: Al igual que una propiedad de margen, que se utiliza para proporcionar el valor de margen a la raíz ya sea en píxeles o en porcentaje (%).
  • umbral: El número que se utiliza para desencadenar la llamada de retorno una vez que el área de la intersección cambia para ser mayor o igual al valor que hemos proporcionado en este ejemplo.

Aparte de estas tres opciones, tenemos una función de observación de la intersección real, que contiene dos parámetros diferentes:

  • El nombre de la función de retrollamada del observador
  • Las opciones adicionales, como la raíz y el umbral

Utilizando el observador de intersección, podemos escuchar cualquier cambio del elemento objetivo, y si hay algún cambio, entonces se activará la función de devolución de llamada.

Ahora vamos a implementar la función de disparo de retrollamada, que se ve así.

12345678910handleObserver(entidades, observador){const y = entidades[0].boundingClientRect.y;if(this.state.prevY> y){const lastPhoto =this.state. photos[this.state.photos.length-1];const curPage = lastPhoto.albumId;this.getPhotos(curPage);this.setState({ page: curPage });}this.setState({ prevY: y });}

jsx

En esta función, configuraremos el número de página en función del elemento objetivo que se esté desplazando. Mantendremos la última página que se esté desplazando, y en función de la página actual, el API de fetch entra en escena y obtiene los últimos datos del servidor.

Tan pronto como desplacemos los datos, la página actual se actualizará en el estado junto con el número de página anterior.

Esto es lo que queríamos desarrollar hasta ahora en esta guía, pero no es el final en absoluto. Dejamos de lado un paso crítico para mostrar las fotos y renderizarlas en el DOM.

Reemplaza la función render() por el código fuente dado.

123456789101112131415161718192021222324252627render(){// Adicional cssconst loadingCSS ={ altura: "100px", margen: "30px"};// Para cambiar el comportamiento del icono de cargaconst loadingTextCSS ={ display:this. state.loading? "block": "none"};return(<divclassName="container"<divstyle={{{{minHeight: "800px"}};{esto. state.photos.map(user={usuario.url}height="100px "width="200px"/))}</div><divref={loadingRef={N-esto. loadingRef= loadingRef)}style={loadingCSS};};spanstyle={loadingTextCSS};}cargando...
jsx

La función de representación contiene una configuración diferente, que se explica a continuación.

Crea algunos estilos adicionales para el icono que se muestra mientras se carga el contenido de esta manera.

1234const loadingCSS ={ altura: "100px", margen: "30px"};

jsx

Otro estilo CSS usado para cambiar la propiedad de clase para el icono de carga se llama loadingTextCSS y se ve así.

1const cargandoTextoCSS ={ display:this.state.loading? "block": "none"};

jsx

Por fin, en la función de retorno, hemos utilizado nuestra matriz de estados, llamada fotos, que contiene la lista de fotos procedentes de la respuesta del API.

12345<divstyle={{{minHeight: "800px"}};{this.state.photos.map(user=§§;(<imgsrc={user.url}height="100px "width="200px"/px;))}</div>

jsx

Junto con la lista de fotos, hemos configurado el icono de carga basado en la referencia de carga para que tan pronto como nos desplacemos hacia abajo al elemento objetivo, muestre el icono de carga. Cuando el proceso de carga se complete, el icono de carga desaparecerá.

123456<divref={cargandoRef={esta.cargandoRef= cargandoRef)}style={cargandoCSS};<spanstyle={cargandoTextoCSS};

jsx

Hemos terminado con nuestro contenido HTML. Ahora, si ejecutamos este ejemplo, obtendremos los 10 registros iniciales por página porque hemos configurado los parámetros adicionales con la API de esta manera.

https://jsonplaceholder.typicode.com/photos?_page=${page}&_limit=10

Así que cuando el usuario se desplaza por la página, el número de página se actualizará con frecuencia; pero el límite de la página se mantiene como está, por lo que se añadirán 10 registros a la vez en la matriz y se renderizarán en el DOM.

Este es el proceso completo para utilizar un observador de intersección para obtener la posición del elemento objetivo y devolver el movimiento al DOM.