在React组件中使用分页API

问题描述 投票:0回答:1

我刚开始使用React。作为一个简单的练习,我想创建一些组件来查看从JsonMonk API中检索到的数据。该API包含83条用户记录,并在10页中提供这些记录。

我正在尝试开发一个组件,以一次称为UserList的方式查看一页用户列表。它的代码如下:

class UserList extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      pageNumber: 1,
      users: [],
    };

    this.onPageNext = this.onPageNext.bind(this);
  }

  componentDidMount() {
    this.fetchUsers(this.state.pageNumber)
      .then((users) => this.setState({users: users}));
  }

  async fetchUsers(pageNumber) {
    const response = await fetch(`https://jsonmonk.com/api/v1/users?page=${pageNumber}`);

    const jsonResponse = await response.json();

    return jsonResponse.data.records;
  }

  onPageNext() {
    // ...
  }

  render() {
    const postElements = this.state.users.map(
      (props) => <User key={props._id} {...props} />);

    return (
      <div>
        {postElements}
        <div>
          <button onClick={this.onPageNext}>Next</button>
        </div>
      </div>
    );
  }
}

我遇到的问题与组件的onPageNext方法有关。当用户单击“下一步”按钮时,我要获取下一页数据并更新列表。

我第一次尝试使用传递给setState的异步箭头函数,如下所示:

  onPageNext() {
    this.setState(async (state, props) => {
      const nextPageNumber = state.pageNumber + 1;

      const users = await this.fetchUsers(nextPageNumber);

      return {pageNumber: nextPageNumber, users: users}
    })
  }

但是,由于状态永远不会更新,因此React似乎不支持这种行为。

接下来,我尝试使用promise .then语法,如下所示:

  onPageNext() {
    const nextPageNumber = this.state.pageNumber + 1;

    this.fetchUsers(nextPageNumber)
      .then((users) => this.setState({pageNumber: nextPageNumber, users: users}));
  }

这有效,但是这里的问题是我直接访问类的状态,而不是通过setState的参数访问,因此我可能会收到不正确的值。假设用户快速单击“下一步”按钮三次,则他们可能无法前进三页。

我基本上遇到了鸡或蛋类型的问题。我需要将回调传递给setState,但我需要知道下一页ID才能提取需要调用setState的数据。在研究了文档之后,我觉得解决方案是将获取逻辑移出UsersList组件,但我不确定如何攻击它。

一如既往,我们将不胜感激。

javascript reactjs rest
1个回答
0
投票

您需要如下更改onPageNext

onPageNext() {
        this.setState( prevState => {
            return {pageNumber: prevState.pageNumber + 1}
        }, () =>{
            this.fetchUsers(this.state.pageNumber).then(users => this.setState({users: users}) )
        });
    }

这里是完整代码:

import React from "react";

export default class UserList extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            pageNumber: 1,
            users: [],
        };

        this.onPageNext = this.onPageNext.bind(this);
    }

    componentDidMount() {
        this.fetchUsers(this.state.pageNumber)
            .then((users) => {
                    console.log(users, 'users');
                    this.setState({users: users})
                }
            );
    }

    async fetchUsers(pageNumber) {
        const response = await fetch(`https://jsonmonk.com/api/v1/users?page=${pageNumber}`);

        const jsonResponse = await response.json();

        return jsonResponse.data.records;
    }

    onPageNext() {
        this.setState( prevState => {
            return {pageNumber: prevState.pageNumber + 1}
        }, () =>{
            this.fetchUsers(this.state.pageNumber).then(users => this.setState({users: users}) )
        });
    }

    render() {
        const postElements = this.state.users.map(
            (user) => <User key={user._id} {...user} />);

        return (
            <div>
                {postElements}
                <div>
                    <button onClick={this.onPageNext}>Next</button>
                </div>
            </div>
        );
    }
}

function User(props) {
    return (
        <div>
            <div style={{padding: 5}}>Name: {props.first_name} {props.last_name}</div>
            <div style={{padding: 5}}>Email: {props.email}</div>
            <div style={{padding: 5}}>Phone: {props.mobile_no}</div>
            <hr/>
        </div>
    );
}

Here is the Code Sandbox

© www.soinside.com 2019 - 2024. All rights reserved.