How to take all pages of an API and show all data at once on screen using React Hooks?

Asked

Viewed 105 times

-1

Hi, I’m studying React Hooks and as a base I’m using a Rick and Morty API to show the characters on the screen https://rickandmortyapi.com/api/character/ However, it only shows twenty characters per page and has a total of 26 pages. I wanted to show all 493 characters on the screen at once. I read the documentation, however, there is no specific query for this. So I tried to do a go through all pages. At the moment, when the code is executed it will show all the characters, but at the end of the loop are only the last 20 characters of the last page on the screen. You can see the result here https://project-soctest.herokuapp.com/

import React, { useState, useEffect } from 'react';
import { CardGrid, Card } from './tableStyled.js';
import Navbar from '../Navbar/Navbar.js';
import api from '../../services/api.js';

const Table = () => {
  const [characters, setCharacters] = useState([]);
  const [numPages] = useState([26]);

   useEffect(() => {
     async function loadData() {
       for(var i = 0; i < numPages; i++){
         const apiResponse = await api.get(`?page=` + i);
         setCharacters(apiResponse.data.results);
      } 
    }
   loadData();
   }, [numPages]); 

  return (
    <div className="container">
      <Navbar/>
       <CardGrid>
         {characters.map(character => (
        <Card key={character.id}>
          <img src={character.image} alt={character.name} />
          <section>
            <header>
              <h3>
                <span>{character.id}</span> {character.name}
              </h3>
              <h4>
                <span>{character.species} - {character.status}</span>
              </h4>
              <h4>
                <span>{character.origin.name}</span>
              </h4>
            </header>
          </section>
        </Card>
    ))};
  </CardGrid>
</div>
);
};

export default Table;

1 answer

0

When you do the "for" to loop and query the other pages of the API, you save the result within the state "characters", then it always deletes the previous value and writes only the current call, why you always have in the state the result of the last page.

To preserve existing values and add new ones, you need to use the Operator spread. Your "setCharacters" would look like this:

setCharacters(prevState => {
    return { ...prevState, apiResponse.data.results}
});

The function loadData would look like this:

async function loadData() {
   for(var i = 0; i < numPages; i++){
    const apiResponse = await api.get(`?page=` + i);
    setCharacters(prevState => {
        return { ...prevState, apiResponse.data.results}
    });
} 

Browser other questions tagged

You are not signed in. Login or sign up in order to post.