Як додати Infinite Scroll в React.js

Чи доводилося вам стикатися з вебсайтами або додатками, де при прокручуванні вниз автоматично підвантажується новий контент? Це і є так зване нескінченне прокручування.

Нескінченне прокручування – це поширений прийом, що спрощує навігацію по великій кількості інформації. Такий підхід часто покращує досвід користувача, особливо на мобільних гаджетах.

Впровадити нескінченне прокручування у React можна декількома способами. Один з них – це використання сторонніх бібліотек, наприклад, react-infinite-scroll-component. Компонент цієї бібліотеки генерує подію, коли користувач прокручує сторінку до кінця. Далі цю подію можна використовувати як сигнал для завантаження додаткових даних.

Інший варіант – застосування вбудованих функцій React. Одна з таких функцій – “componentDidMount”, яка спрацьовує, коли компонент вперше монтується.

Використовуючи “componentDidMount”, можна завантажити початкову порцію даних, а потім “componentDidUpdate” для підвантаження наступних блоків, коли користувач гортає сторінку.

Також для створення нескінченного прокручування можна застосувати хуки React.

Існує декілька варіантів використання компонента react-infinite-scroll.

Інсталяція компонента react-infinite-scroll

Щоб почати роботу, спершу потрібно встановити його через npm:

 npm install react-infinite-scroll-component --save 

Імпорт react-infinite-scroll-component у React

Після інсталяції необхідно імпортувати бібліотеку нескінченного прокручування у свій React-компонент.

 import React from 'react'
import InfiniteScroll from 'react-infinite-scroll-component'
 
class App extends React.Component {
  constructor() {
    super()
    this.state = {
      items: [],
      hasMore: true
    }
  }

  componentDidMount() {
    this.fetchData(1)
  }
 
  fetchData = (page) => {
    const newItems = []
 
    for (let i = 0; i < 100; i++) {
      newItems.push(i )
    }
 
    if (page === 100) {
      this.setState({ hasMore: false })
    }
 
    this.setState({ items: [...this.state.items, ...newItems] })
  }
 
  render() {
    return (
      <div>
        <h1>Infinite Scroll</h1>
        <InfiniteScroll
          dataLength={this.state.items.length}
          next={this.fetchData}
          hasMore={this.state.hasMore}
          loader={<h4>Loading...</h4>}
          endMessage={
            <p style={{ textAlign: 'center' }}>
              <b>Yay! You have seen it all</b>
            </p>
          }
        >
          {this.state.items.map((item, index) => (
            <div key={index}>
              {item}
            </div>
          ))}
        </InfiniteScroll>
      </div>
    )
  }
}
 
export default App

Наведений код імпортує React та компонент InfiniteScroll з бібліотеки react-infinite-scroll-component. Далі створюється компонент зі станом, який ініціалізується порожнім масивом елементів і прапором hasMore зі значенням True.

Налаштування параметрів

У методі життєвого циклу componentDidMount потрібно викликати метод fetchData з параметром сторінки, що дорівнює 1. Метод fetchData здійснює запит до API для отримання даних. У наведеному прикладі react-infinite-scroller генерує фіктивні дані та створює масив зі 100 елементів.

Коли значення параметра сторінки досягне 100, оскільки елементів більше не буде, прапорець hasMore змінюється на False. Це зупиняє компонент InfiniteScroll від подальших запитів до API. Наостанок стан компонента оновлюється новими даними.

Метод render використовує компонент InfiniteScroll та передає йому певні параметри. Атрибут dataLength встановлюється як довжина масиву елементів. Для атрибуту next встановлюється метод fetchData. Атрибут hasMore відповідає значенню прапорця hasMore.

Атрибут loader змушує компонент відображати повідомлення про завантаження, а атрибут endMessage показує повідомлення після завантаження всіх даних.

Можна передавати й інші атрибути компоненту InfiniteScroll, але наведені вище використовуються найчастіше.

Використання вбудованих функцій

React має декілька вбудованих методів, які можна застосувати для реалізації InfiniteScroll.

Перший метод – це componentDidUpdate. React викликає його після оновлення компонента. У цьому методі можна перевірити, чи користувач прокрутив сторінку до кінця. Якщо так, то завантажуються нові дані.

Другий метод – це onScroll, який React викликає, коли користувач прокручує сторінку. За допомогою нього можна відстежувати положення прокрутки та завантажувати більше даних, коли користувач доходить до кінця сторінки.

Нижче наведено приклад нескінченного прокручування в React з використанням цих методів:

 import React, {useState, useEffect} from 'react'
 
function App() {
  const [items, setItems] = useState([])
  const [hasMore, setHasMore] = useState(true)
  const [page, setPage] = useState(1)
 
  useEffect(() => {
    fetchData(page)
  }, [page])
 
  const fetchData = (page) => {
    const newItems = []
 
    for (let i = 0; i < 100; i++) {
      newItems.push(i)
    }
 
    if (page === 100) {
      setHasMore(false)
    }
 
    setItems([...items, ...newItems])
  }
 
  const onScroll = () => {
    const scrollTop = document.documentElement.scrollTop
    const scrollHeight = document.documentElement.scrollHeight
    const clientHeight = document.documentElement.clientHeight
 
    if (scrollTop + clientHeight >= scrollHeight) {
      setPage(page + 1)
    }
  }
 
  useEffect(() => {
    window.addEventListener('scroll', onScroll)
    return () => window.removeEventListener('scroll', onScroll)
  }, [items])
 
  return (
    <div>
      {items.map((item, index) => (
        <div key={index}>
          {item}
        </div>
      ))}
    </div>
  )
}
 
export default App

Цей код використовує хуки useState та useEffect для керування станом і побічними ефектами.

У хуку useEffect викликається метод fetchData з поточною сторінкою. Метод fetchData здійснює запит до API для отримання даних. У прикладі для демонстрації техніки створюються фіктивні дані.

Цикл for заповнює масив newItems 100 цілими числами. Якщо параметр сторінки дорівнює 100, то прапорець hasMore змінюється на False. Це зупиняє компонент нескінченної прокрутки від подальших запитів до API.

Наостанок стан компонента оновлюється новими даними.

Метод onScroll відстежує положення прокрутки та завантажує більше даних, якщо користувач прокручує сторінку до кінця.

Хук useEffect додає слухач подій для події прокрутки. Коли ця подія спрацьовує, то викликається метод onScroll.

У нескінченного прокручування в React є свої переваги та недоліки. З одного боку, це покращує зручність користування, особливо на мобільних пристроях. З іншого – користувачі можуть пропустити частину контенту, якщо не прокрутять сторінку достатньо вниз.

Важливо зважити всі “за” і “проти” перед тим, як застосовувати нескінченне прокручування на вебсайті чи в додатку.

Додавання нескінченного прокручування на сайт або в додаток React.js може покращити взаємодію користувача. Завдяки такому підходу користувачам не потрібно клікати, щоб побачити більше інформації. Використання Infinite Scroll у додатку React.js може зменшити кількість завантажень сторінок, що покращує продуктивність.

Також можна безкоштовно розмістити свій React-додаток на сторінках Github.