首页 > 解决方案 > 更新 axios 请求分页

问题描述

我有一个显示数据数组的 axios GET 请求,但一次只显示 15 个项目。API url 使用多个页面,例如example.com/?page=1. 我想创建某种分页,我可以在其中选择下一页,它将 GET 请求更改为下一页。如何根据我选择的页码更改 url 页码?

这是我当前的 componentDidMount 请求,所以当我到达页面时,

componentDidMount() {
    const access_token = JSON.parse(localStorage['appState']).user
        .access_token;

    const config = {
        headers: {
            Authorization: 'Bearer ' + access_token,
        },
    };

    axios
        .get('https://exammple.com/api/v1/job?page=1', config)

        .then((response) => {
            // handle success
            console.log(response.data.data);
            this.setState({ jobs_info: response.data.data });
        })
        .catch((error) => {
            if (error.response) {
                // The request was made and the server responded with a status code
                // that falls out of the range of 2xx
                console.log(error.response.data);
                console.log(error.response.status);
                console.log(error.response.headers);
            } else if (error.request) {
                // The request was made but no response was received
                // `error.request` is an instance of XMLHttpRequest in the browser and an instance of
                // http.ClientRequest in node.js
                console.log(error.request);
            } else {
                // Something happened in setting up the request that triggered an Error
                console.log('Error', error.message);
            }
            console.log(error.config);
        });
}

标签: javascriptreactjsaxios

解决方案


我想创建某种分页,我可以在其中选择下一页

像这样创建分页组件:

function PageSelector(props) {
  const pages = [];

  for (let i = 1; i <= props.numberOfPages; i++) {
    pages.push(
      <div key={i} onClick={() => props.handleClick(i)}>{i}</div>
    );
  }

  return <div>{pages}</div>;
}

该组件呈现页面按钮(它需要良好的样式,但为了清楚起见,我将其保留)。

每次单击带有页码的按钮都会<App />使用以下功能更新组件状态handleClick

export default class App extends React.Component {
  constructor(props) {
    // ...
    this.state = {
      currentPage: 1,
      numberOfPages: 5
    };
  }

  handleClick(value) {
    this.setState({ currentPage: value });
  }
  
  render() {
    return (
      <div className="App">
        <PageSelector handleClick={this.handleClick} />
      </div>
    );
}

  // ...
}

currentPage值被传递给CommentsView组件以请求 API。每次更改CommentsView都会更新组件数据。currentPage

class CommentsView extends React.Component {
  constructor(props) { /* ... */ }

  componentDidMount() {
    this.getComments(this.props.postId);
  }

  componentDidUpdate() {
    this.getComments(this.props.postId);
  }

  getComments(postId) {
    axios
      .get(`https://jsonplaceholder.typicode.com/posts/${postId}/comments`)
      .then(response => this.setState({ comments: response.data }))
      .catch(error => console.log(error));
  }

  render() { /* ... */ }
}

您需要同时使用生命周期方法 -componentDidMountcomponentDidUpdate. 第一个在第一次渲染组件时运行,第二个在每次组件更新时运行。

这是您可以根据您选择的页码更改 URL 的方法。


以下是您可以用作参考的完整示例代码:

import React from "react";
import axios from "axios";

export default class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      currentPage: 1,
      numberOfPages: 5
    };
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick(value) {
    this.setState({ currentPage: value });
  }

  render() {
    return (
      <div className="App">
        <CommentsView postId={this.state.currentPage} />
        <PageSelector
          currentPage={this.state.currentPage}
          numberOfPages={this.state.numberOfPages}
          handleClick={this.handleClick}
        />
      </div>
    );
  }
}

function PageSelector(props) {
  const itemStyle = {
    display: "flex",
    justifyContent: "center",
    alignItems: "center",
    width: "30px",
    height: "30px",
    margin: "0 5px",
    border: "1px solid"
  };

  const pages = [];

  for (let i = 1; i <= props.numberOfPages; i++) {
    pages.push(
      <div key={i} onClick={() => props.handleClick(i)} style={itemStyle}>
        {i}
      </div>
    );
  }

  return <div style={{ display: "flex" }}>{pages}</div>;
}

class CommentsView extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      comments: []
    };
  }

  componentDidMount() {
    this.getComments(this.props.postId);
  }

  componentDidUpdate() {
    this.getComments(this.props.postId);
  }

  getComments(postId) {
    axios
      .get(`https://jsonplaceholder.typicode.com/posts/${postId}/comments`)
      .then(response => this.setState({ comments: response.data }))
      .catch(error => console.log(error));
  }

  render() {
    const comments = this.state.comments.map(comment => (
      <li key={comment.id}>{comment.body}</li>
    ));

    return comments.length > 0 ? <ul>{comments}</ul> : <span>loading</span>;
  }
}

codesandbox.io 的链接


推荐阅读