es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

IntersectionObserver no se activa cuando el div ref se renderiza condicionalmente.

Estoy tratando de construir una paginación de scroll infinito en React, y utilizando el IntersectionObserver de JavaScript para adjuntar un div de carga adicional. Básicamente, cuando el usuario se desplaza hacia abajo hasta la tabla, se mostrará el texto “Cargando…” y se llamará a una API para obtener el contenido de la tabla desde el backend. El problema es que si muestro el texto “Cargando…” sin renderizar ninguna condición, el IntersectionObserver se activa correctamente, pero cuando agrego una condición para renderizar el texto “Cargando…”, el IntersectionObserver no se activa en absoluto.

Desde la API de backend, obtendré la variable “numberOfPages”, que definirá cuántas páginas/registros hay en la base de datos, y no debería aparecer el texto “Cargando…” después de llegar a la última página. Esto es lo que he intentado hasta ahora. También probé uno de los blogs que encontré en el siguiente enlace: Blog Link.

Código en Codesandbox: Enlace al código.

En vivo: Demo en vivo aquí.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Construyendo paginación de desplazamiento infinito en React con IntersectionObserver

    Problema

    El usuario está tratando de implementar una funcionalidad de paginación de desplazamiento infinito en React utilizando IntersectionObserver de JavaScript. La idea es mostrar un texto de “Cargando…” cuando el usuario haga scroll hasta la tabla y llamar a una API para obtener más contenido de la tabla desde el backend. El problema es que cuando se agrega una representación condicional para mostrar el texto de “Cargando…” solo cuando la llamada anterior a la API no ha finalizado, el IntersectionObserver no se activa en absoluto.

    Solución

    El problema probablemente esté causado por la representación condicional del texto de “Cargando…” que puede impedir que el IntersectionObserver se active correctamente. Una solución es usar una variable de estado para realizar un seguimiento de si hay una llamada a la API en progreso y representar el texto de “Cargando…” en función del valor de esta variable.

    Aquí hay un fragmento de código modificado para implementar esta solución:

    import React, { useState, useRef, useEffect } from 'react';
    
    function App() {
      const [isFetching, setIsFetching] = useState(false);
      const [data, setData] = useState([]);
      const [pageNumber, setPageNumber] = useState(1);
      const numberOfPages = 10;
    
      const observer = useRef();
      const lastElementRef = useRef();
    
      const fetchData = async (page) => {
        setIsFetching(true);
        const response = await fetch(`https://api.example.com/data?page=${page}`);
        const newData = await response.json();
        setData((prevData) => [...prevData, ...newData]);
        setIsFetching(false);
      };
    
      const handleObserver = (entities) => {
        const target = entities[0];
        if (target.isIntersecting && pageNumber < numberOfPages && !isFetching) {
          setPageNumber((page) => page + 1);
        }
      };
    
      useEffect(() => {
        if (!observer.current) {
          observer.current = new IntersectionObserver(handleObserver, {
            root: null,
            rootMargin: '0px',
            threshold: 1.0,
          });
        }
        if (lastElementRef.current) {
          observer.current.observe(lastElementRef.current);
        }
      }, [lastElementRef, handleObserver]); // incluir handleObserver como dependencia
    
      useEffect(() => {
        fetchData(pageNumber);
      }, [pageNumber]); // volver a buscar datos cuando cambie el número de página
    
      return (
        <div classname="App">
          <table>
            <tbody>
              {data.map((item, index) => (
                <tr key="{index}">
                  <td>{item.name}</td>
                  <td>{item.description}</td>
                </tr>
              ))}
            </tbody>
          </table>
          {isFetching && <div>Cargando...</div>}
          {!isFetching && pageNumber < numberOfPages && <div ref="{lastElementRef}">Cargando más...</div>}
        </div>
      );
    }
    
    export default App;
    

    En este código modificado, introducimos una nueva variable de estado isFetching para realizar un seguimiento de si hay una llamada a la API en progreso. Cuando se llama a la función handleObserver, verificamos si hay más páginas para obtener, si no hay una llamada anterior a la API en progreso y si el elemento objetivo se está intersecando. Si se cumplen todas las condiciones, incrementamos el número de página y activamos una nueva llamada a la API.

    Representamos el texto de “Cargando…” según el valor de isFetching y solo mostramos el texto de “Cargando más…” cuando haya más páginas para obtener y no haya una llamada anterior a la API en progreso. También utilizamos lastElementRef para observar el último elemento de la tabla y activar la función handleObserver cuando esté en vista.

    Con estos cambios, el IntersectionObserver debería activarse correctamente y el texto de “Cargando…” solo se mostrará cuando sea necesario, sin interferir con el IntersectionObserver.

Comments are closed.