-1

I am using an API to fetch data, but in order to fetch all the data I am required to loop through the links

 const [characterData, setCharacterData] = useState([]);
 const [link, setLink] = useState("https://swapi.dev/api/people/");

    useEffect(() => {
        getData();
    }, [])

    async function getData() {
        while (link) {
            const fetchedData = await fetch(link);
            const jsonData = await fetchedData.json();
            setCharacterData([...characterData, jsonData.results]);
            setLink(jsonData.next);
            console.log(link)
        }
        
    }

This is how one of the jsonData from above would look like:

{ "next": "http://swapi.dev/api/people/?page=2", "previous": null, "results": [list of the wanted data] }

The last object will have "next": null, so the while loop should end at some point, but for some reason setLink() never updates the link and causes it to become an infinite loop. Link always remains as "https://swapi.dev/api/people/".

Another problem is that the page isn't displaying anything as characterData gets updated, so I am assuming that characterData isn't updating either, but I am not sure.

characterData.map((character, index) => {
      return (
           <div className="character-item" key={index}>
               <h4>{character.name}</h4>
               <p>{character.birth_year}</p>
           </div>
      );
})

Note: Each character is an object

Thank you!

Patrick Roberts
  • 49,224
  • 10
  • 102
  • 153
Anonymous
  • 39
  • 3

1 Answers1

1

The link is declared with const - it'll never change in a given render. So the

while (link) {

will run forever.

Unless you're using the link elsewhere, I'd remove it from state entirely and use a local variable inside getData instead. Make sure to use the callback form of setCharacterData too so that you don't lose the prior value in state.

async function getData() {
    let link = 'https://swapi.dev/api/people/';
    while (link) {
        const fetchedData = await fetch(link);
        const jsonData = await fetchedData.json();
        setCharacterData(characterData => [...characterData, jsonData.results]);
        link = jsonData.next;
    }
}

It would also be a great idea to catch possible errors:

useEffect(() => {
    getData()
        .catch(handleErrors);
}, [])
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320