@Feed-back

Как загружать посты по мере прокрутки страницы?

В componentDidMount на window вешается листанер на скрол, если страничку скролят почти до конца(вся страница - 200px) дергается метод с бека (getAllNews), который возвращает посты, этот метод принимает в себя 2 параметра, сколько нужно пропустить постов и сколько взять из полного списка постов которые лежат на бэке.
Например если у нас изначально подгружается первые 3 поста, то этот метод дергается с параметрами 0 (сколько пропускаем) и 3 (сколько постов берем), дальше когда скроллим страничку почти до конца этот метод дергается снова но уже с параметрами 3 (сколько нужно пропустить) и 3 (сколько нужно взять) и параллельно увеличивается локальное поле в state отвечающее за то сколько нужно пропустить
По скольку setState асинхронный, метод getAllNews может дергаться с одними теми же параметрами, если пользователь будет быстро скролить, ибо он дергается на каждый скрол и если state еще не изменился то он отправляет одинаковые запросы
Вопрос в следующем, как сделать так, что бы getAllNews не вызывался пока не отработает setState от прошлого скрола?
state = {
    list: [],
    skip: 5
  };
  componentDidMount() {
    service
      .getAllNews(0, 5)
      .then((body) => {
        this.setState(() => {
          return {
            list: body.newsSlims,
            total: body.total,
          };
        });
      })
      .then(() => {
        window.addEventListener("wheel", (e) => {
          let windowBottom = document.documentElement.getBoundingClientRect()
            .bottom;
          if (
            windowBottom < document.documentElement.clientHeight + 400 &&
            this.state.total > this.state.skip
          ) {
            service.getAllNews(this.state.skip, 5).then((body) => {
              this.setState(() => {
                return {
                  skip: this.state.skip + 5,
                  list: this.state.list.concat(body.newsSlims),
                };
              });
            });
          }
        });
      });
  }
  • Вопрос задан
  • 156 просмотров
Пригласить эксперта
Ответы на вопрос 1
achubutkin
@achubutkin
Взводите флаг (локальная приватная переменная класса), затем в обработчике скролла:
if (!this._allowInfinite) return;
this._allowInfinite = false;

// ...вызов API
// ...в then, после завершения вызова
this._allowInfinite = true;

Не нужно все делать через setState, а если все таки делаете, то для синхронизации см. коллбэк в функции setState.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы