Как добавить кнопку «загрузить еще», чтобы загрузить следующие 50 запросов от вызова Axios? - PullRequest
1 голос
/ 15 октября 2019

Прямо сейчас мой код находится ниже, у меня есть начало URL в моем прокси:

import React, { Component } from "react";
import axios from "axios";

class BeerList extends Component {
  state = {
    beers: []
  };

  componentDidMount() {
    axios
      .get(`/beers/?key=6f8f96d8bd670a389ec963899a8e958d`)
      .then(res => {
        console.log(res);
        this.setState({ beers: res.data.data });
      })
      .catch(err => console.log(err));
  }

  render() {
    return (
      <ul>
        {this.state.beers.map(beer => (
          <li key={beer.id}>{beer.name}</li>
        ))}
      </ul>
    );
  }
}
export default BeerList;

Я получаю первые 50 элементов из этого API, но хочу отобразить кнопку загрузки еще нанижняя часть, чтобы загрузить следующие 50 и так далее. Как это возможно?

1 Ответ

2 голосов
/ 15 октября 2019

Согласно документации , вы можете передать параметр запроса p для запроса конкретной страницы.

Во-первых, вы можете изолировать выборку от вашего компонента с помощью простой функции(в том же файле или другом файле).

async function fetchBeerList(key, { page }) {
  return axios
    .get("https://sandbox-api.brewerydb.com/v2/", {
      params: {
        key,
        p: page
      }
    })
    // Pre-parse Axios' `data` nesting.
    .then(({ data }) => data);
}

Тогда компонент может выглядеть примерно так:

class BeerList extends Component {
  state = {
    beers: [],
    currentPage: 0,
    numberOfPages: 0
  };

  componentDidMount() {
    // Reusing the same callback as our button
    this.fetchMoreBeers();
  }

  componentWillUnmount() {
    // Simple flag to avoid state updates if the component was unmounted before
    // our fetch had the time to finish.
    this._unmounted = true;
  }

  fetchMoreBeers = () => {
    const { beerId } = this.props;
    const { currentPage } = this.state;

    this.setState({ isFetching: true });

    fetchBeerList(beerId, { page: currentPage + 1 }).then(
      this.updateBeers,
      this.onFailure
    );
  };

  onFailure = err => {
    // avoid updating state on an unmounted component
    if (this._unmounted) return;

    this.setState({ isFetching: false, err });
  };

  updateBeers = ({ currentPage, numberOfPages, data }) => {
    // avoid updating state on an unmounted component
    if (this._unmounted) return;

    this.setState(({ beers }) => ({
      isFetching: false,
      beers: beers.concat(data),
      currentPage,
      numberOfPages
    }));
  };

  render() {
    const { beers, isFetching, currentPage, numberOfPages } = this.state;

    return (
      <div>
        <ul>
          {beers.map(beer => (
            <li key={beer.id}>{beer.name}</li>
          ))}
        </ul>
        {!isFetching && currentPage < numberOfPages && (
          <button type="button" onClick={this.fetchMoreBeers}>
            See more
          </button>
        )}
      </div>
    );
  }
}

Кнопка отображается, только если число страниц большечем текущий индекс страницы, или если мы еще не выбираем.

Также предполагается, что вы получаете beerId в качестве реквизита.

<BeerList beerId="6f8f96d8bd670a389ec963899a8e958d" />

Чтобы минимизироватьшум в JSX, я предпочитаю деструктурировать все, что мне нужно.

const { beers, isFetching, currentPage, numberOfPages } = this.state;

Для обеспечения этого в проектах, над которыми я работаю, мы используем react/destructuring-assignment правило реагирования подключаемого модуля eslint .

В дополнение к улучшениям читабельности, это гарантирует, что никакие контекстные кошмары не могут случиться с чем-то вроде this.props.onClick(), использующим неправильный this и играющим с неизменными подпорками.


Узнайте больше оthis._unmounted.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...