如何添加更多加载按钮以从axios调用中加载下一个50个请求?

时间:2019-10-15 18:27:06

标签: javascript reactjs axios

现在我的代码在下面,我在代理中有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;

我正在从此api获取前50个项目,但想在底部显示“加载更多”按钮以加载下一个50,依此类推。这怎么可能?

1 个答案:

答案 0 :(得分:2)

根据the documentation,您可以传递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's react plugin rule

除了提高可读性之外,它还确保使用错误的this.props.onClick()并弄乱不可变的道具时,this之类的事情不会发生上下文噩梦。


Read more about this._unmounted.