Як реалізувати нескінченну прокрутку в React за допомогою Intersection Observer API

pic

Чи коли-небудь ви замислювались, як працює нескінченна прокрутка на таких сайтах, як Facebook, Twitter чи Instagram? У цьому підручнику ми дізнаємось, як реалізувати нескінченну прокрутку в додатку на React або Next.js за допомогою Intersection Observer API.

Intersection Observer API

Intersection Observer API — це сучасний веб-API, який дозволяє спостерігати за змінами в перетині цільового елемента з предком або з видимою частиною екрана. Цей API часто використовують для реалізації таких функцій, як ліниве завантаження зображень, нескінченна прокрутка та інші. Раніше нескінченну прокрутку зазвичай реалізували за допомогою прослуховувачів подій прокрутки, але з появою Intersection Observer API це стало набагато ефективніше.

Тепер давайте подивимось, як можна використати цей API для реалізації нескінченної прокрутки в компоненті на React.

Компонент Постів

Уявімо, що в нас є компонент Posts, який отримує список постів з API і відображає їх у вигляді карток. Ми реалізуємо нескінченну прокрутку, щоб завантажувати більше постів, коли користувач прокручує сторінку вниз.

Спочатку ми почнемо без нескінченної прокрутки, просто відображатимемо список постів після одного виклику API.

import React, { useEffect, useState } from "react";  
import { getPosts } from "./actions";  
import Post from "./post";  

export default function Posts() {  
 const [posts, setPosts] = useState([]);  

 useEffect(() => {  
 const fetchPosts = async () => {  
 try {  
 const response = await getPosts(0); // getPosts викликає API для отримання постів, передаючи номер сторінки. Ми передаємо 0 для отримання першої сторінки.  
 setPosts(response.data);  
 } catch (error) {  
 console.error("Помилка при отриманні постів:", error);  
 }  
 };  

 fetchPosts();  
 }, []);  

 return (  

    {posts.map((post) => (     // Post відображає дані поста у форматі картки    ))}    
    );   
}  

Реалізація нескінченної прокрутки

Щоб реалізувати нескінченну прокрутку, потрібно зробити наступне:

Додати стан для пагінації та статусу завантаження

const [page, setPage] = useState(0);   
const [hasMore, setHasMore] = useState(true);   
const [isLoading, setIsLoading] = useState(false);  

Використовувати Intersection Observer для виявлення прокрутки

Якщо ми безпосередньо використовуємо Intersection Observer API, нам потрібно обробляти налаштування та демонтаж спостерігача, що може бути складним. Замість цього ми можемо використати бібліотеку react-intersection-observer, яка надає хук React для легкого спостереження за елементами у видимій частині екрана.

Ми будемо використовувати хук useInView з бібліотеки react-intersection-observer, щоб виявити, коли користувач прокрутив до низу списку.
Коли останній пост потрапляє в поле зору, ми завантажуємо більше постів, викликаючи функцію fetchPosts з наступним номером сторінки.

Ось фінальна реалізація компонента Posts з нескінченною прокруткою:

import React, { useEffect, useState } from "react";  
import { getPosts } from "./actions";  
import Post from "./post";  
import { useInView } from "react-intersection-observer";  

export default function Posts() {  
 const [posts, setPosts] = useState([]);  
 const [page, setPage] = useState(0);  
 const [hasMore, setHasMore] = useState(true);  
 const [isLoading, setIsLoading] = useState(false);  
 const [scrollTrigger, isInView] = useInView();  

 const fetchPosts = async (page: number) => {  
 setIsLoading(true);  
 try {  
 const response = await getPosts(page);  
 setPosts((prevPosts) => [...prevPosts, ...response.data]);  
 setHasMore(response.data.length > 0);  
 } catch (error) {  
 console.error("Помилка при отриманні постів:", error);  
 } finally {  
 setIsLoading(false);  
 }  
 };  

 useEffect(() => {  
 fetchPosts(page);  
 }, [page]);  

 useEffect(() => {  
 if (isInView && hasMore && !isLoading) {  
 setPage((prevPage) => prevPage + 1);  
 }  
 }, [isInView, hasMore, isLoading]);  

 return (  

    {posts.map((post) => (     // Відображає дані поста у форматі картки    ))}    
    {(hasMore &&     
Завантаження...
    ) || (    
Немає більше постів для завантаження
    )}    
    );   
}  

Хук useInView повертає два значення: scrollTrigger та isInView. scrollTrigger — це реф, який потрібно прикріпити до елемента, який ви хочете спостерігати. В даному випадку ми прикріплюємо його до елемента div в кінці списку постів. isInView — це булеве значення, яке вказує, чи знаходиться елемент з рефом scrollTrigger в полі зору. Коли елемент з scrollTrigger потрапляє в поле зору, ми збільшуємо стан page, щоб завантажити більше постів. Функція fetchPosts викликається щоразу, коли змінюється стан page, і отримує пости для вказаного номера сторінки, додаючи їх до наявного списку постів.

Ви можете знайти повний вихідний код тут.

Висновок

У цьому підручнику ми дізналися, як реалізувати нескінченну прокрутку в додатку на React або Next.js, використовуючи Intersection Observer API. Завдяки бібліотеці react-intersection-observer ми змогли визначити, коли користувач прокрутив до низу списку, і завантажити більше постів динамічно. Цю техніку можна застосувати в різних сценаріях, де потрібно завантажувати контент по мірі прокрутки сторінки.

Щоб бути в курсі останніх підручників з веб-розробки, підписуйтесь на нас в youtube, linkedin і medium.

Відео-версія

У відео нижче ви можете знайти детальніше пояснення вищеописаної реалізації.

https://youtu.be/-LJuz45xfOM

Оригінал опубліковано на https://codewiz.info.

Перекладено з: How to implement Infinite Scroll in React using Intersection Observer API

Leave a Reply

Your email address will not be published. Required fields are marked *