Scroll infinito en React con IntersectionObserver

Guía de scroll infinito en React

Scroll infinito en React: hook con IntersectionObserver | We.Inc

Crea scroll infinito en React con un pequeño hook de IntersectionObserver, sin necesidad de paquetes, y mantén rápidos los feeds largos con virtualización. Demos en vivo y código para copiar.

Coloca un elemento centinela vacío después del último elemento y obsérvalo con IntersectionObserver. Cuando llegue a unos cientos de píxeles del viewport, pide la siguiente página y añádela. Un hook de veinte líneas lo hace sin librerías. Cuando la lista llegue a miles de filas, añade virtualización para que solo existan en el DOM las filas visibles.

Opciones de IntersectionObserver que importan para el scroll infinito

Las dos demos de abajo se ejecutan en esta página. La primera carga páginas de resultados falsos mientras desplazas su panel; la segunda recorre diez mil filas dibujando solo las veinte o así que puedes ver. Debajo está el código de cada una, listo para copiar.

Preguntas frecuentes

¿Necesito una librería para el scroll infinito en React?

No. IntersectionObserver está disponible en todos los navegadores principales desde 2019, y un hook pequeño cubre el caso habitual. Una librería de obtención de datos con utilidades de paginación integradas vale la pena cuando ya usas una para cachear peticiones.

¿Qué es la virtualización y cuándo la necesito?

La virtualización renderiza solo las filas dentro de la ventana visible más un pequeño margen, colocadas dentro de un espaciador con la altura total de la lista. Recurre a ella cuando el DOM tenga miles de filas y el desplazamiento o la escritura empiecen a ir lentos. @tanstack/react-virtual y su hook useVirtualizer son una opción habitual.

¿El scroll infinito es malo para el SEO?

Los rastreadores de los buscadores no se desplazan como las personas, así que el contenido que solo aparece al desplazarse puede no verse nunca. Respalda el feed con URLs paginadas reales como ?page=2 que carguen por sí solas, y enlázalas.

¿Por qué mi observer se dispara una y otra vez?

Normalmente el efecto vuelve a crear el observer en cada render porque el callback cambia de identidad, o la primera página es demasiado corta para sacar el centinela de la pantalla. Guarda el callback más reciente en una ref y asegúrate de que cada página ocupe más que el viewport.

Por qué un centinela es mejor que los eventos scroll

Carga, errores y el final de la lista

El hook useInfiniteScroll

useInfiniteScroll.ts

Devuelve una ref para el centinela. El onLoadMore más reciente se guarda en una ref para que el observer se cree una vez por cada cambio de enabled, no en cada render.

Feed.tsx usando el hook

La marca de carga evita las peticiones dobles, y hasMore desactiva el observer al final.

Virtualizar una lista larga con TanStack Virtual

Instálalo con npm install @tanstack/react-virtual. La caja exterior se desplaza, la interior es tan alta como toda la lista y cada fila visible se coloca en su sitio con translateY.

VirtualList.jsx

Solo se renderizan las filas cercanas a la ventana visible. estimateSize es la altura de la fila en píxeles.

Demo: un feed que carga mientras te desplazas

Desplázate dentro del panel. Llega una página nueva de diez elementos cada vez que el centinela entra en el rango, hasta ocho páginas.

Demo del feed

Publicación {n}

Cargando...

Has llegado al final.

Cargar más

{items} elementos, página {page} de {last}

Reiniciar

Demo: 10,000 filas, solo se renderizan las visibles

Desplaza la lista y observa qué pocas filas existen realmente en la página en cada momento.

Demo de lista virtual

Fila {n}

Renderizando {shown} de {total} filas

Empieza gratis · Sin tarjeta de crédito

Relacionado: Guías

Producto

Para quién es

Funciones

Recursos

Empresa

Mapa del sitio