如何从API解构对象?

时间:2019-04-11 11:33:53

标签: reactjs axios

我正在从(https://reqres.in/api/users)调用API,我们能否将该API分解为单个对象数组。这样我就可以自定义API中固定的每页。

This is Codepen link https://codepen.io/monukr14/pen/oOWpyq



Initial API Format

{
  "page": 1,
  "per_page": 3,
  "total": 12,
  "total_pages": 4,
  "data": [
    {
      "id": 1,
      "first_name": "George",
      "last_name": "Bluth",
      "avatar": "https://s3.amazonaws.com/uifaces/faces/twitter/calebogden/128.jpg"
    },
    {
      "id": 2,
      "first_name": "Janet",
      "last_name": "Weaver",
      "avatar": "https://s3.amazonaws.com/uifaces/faces/twitter/josephstein/128.jpg"
    },
    {
      "id": 3,
      "first_name": "Emma",
      "last_name": "Wong",
      "avatar": "https://s3.amazonaws.com/uifaces/faces/twitter/olegpogodaev/128.jpg"
    }
  ]
}

1 个答案:

答案 0 :(得分:0)

在这里,您将必须进行多个API调用,所有这些调用均基于上一个调用。 This is pretty much the example case for async await.

// default start at page #1
async function makeRequest(page = 1) {
    const url = `https://reqres.in/api/users?page=${page}`
    const response = await axios.get(url);

    const { total_pages: totalPages, data } = response.data;

    const isLastPage = totalPages <= page;
    if (isLastPage) {
        return data; // if last page, just return this data
    }

    const next = await makeRequest(page + 1); // make request for next page
    return [...next, ...data] // return both sets of data
}

这是一个处理请求的功能。如果要获取更多页面,它将递归调用API。

然后我们可以使用您的componentDidMount方法很好地处理它。

componentDidMount() {
  makeRequest()
    .then(repos => this.setState({ repos }))
    .catch(error => console.log(error));
}

===编辑===

再三考虑,我想更新我以前的答案,因为它不可扩展。 它显示了所有请求完成后的所有用户-在4页上并不明显,但是在大量页面上会出现问题。

async function makeRequest(page = 1) {
  const url = `https://reqres.in/api/users?page=${page}`;
  const response = await axios.get(url);

  const { total_pages: totalPages, data } = response.data;

  return { totalPages, repos: data };
}

class Repos extends React.Component {
  state = {
    repos: []
  };

  async componentDidMount() {
    this.loadPages();
  }

  async loadPages() {
    const totalPages = await this.loadPage(1); // make first request

    const nextPage = 2;
    for (let i = nextPage; i <= totalPages; i++) { // make every request separately
      this.loadPage(i);
    }
  }

  async loadPage(page = 1) {
    const { totalPages, repos } = await makeRequest(page);
    this.addRepos(repos);

    return totalPages;
  }

  addRepos(repos) {
    this.setState(prevState => ({
      repos: [...repos, ...prevState.repos] // add to array, not override
    }));
  }
....
}

我更新的代码分别发出每个请求,并将其追加到状态中(而不是覆盖它)。这意味着它可以独立发出请求,并在每个请求完成后立即添加用户。

这确实意味着顺序不一定与API匹配,但这可以通过根据需要对状态进行排序来更改。

You can see it working on CodePen here.