I'm trying to write a React functional component that requests a list of people exposed across multiple pages in an API:
https://swapi.dev/api/people/?page=9
I know there are currently nine pages, but this might change in the future, so I want my component to keep requesting pages until there are no more, and to accumulate and store the people in the "results"
bit of each response body. I'm trying to do this with useState
and useEffect
hooks.
Is there a common way of solving this problem that's generally considered the best approach?
Could someone show me how to modify my existing code to get it working in the optimal way please?
My current code causes the browser to get stuck endlessly loading.
Was I wrong to try and handle the entire process in the first and only execution of useEffect
? Should my useState
have a dependency array that gets passed page
so that useEffect
executes again every time page
is updated?
import React, { useState, useEffect } from 'react';
function GetAllPeople() {
const [page, setPage] = useState(1)
const [people, setPeople] = useState([]);
const [gotEveryone, setGotEveryone] = useState(false)
const [error, setError] = useState(null)
const requestData = () => (
fetch(`https://swapi.dev/api/people/?page=${page}`)
.then(res => {
if (res.ok) {
let response = res.json()
setPeople(people.concat(response.results))
setPage(page + 1)
} else if(res.status === 404) {
setGotEveryone(true)
} else {
setError(res.status)
return Promise.reject('some other error: ' + res.status)
}
})
)
useEffect(() => {
while(gotEveryone === false) {
if (!error) {
requestData()
}
}
})
return (
<div>
<ul>
{people.map((person, index) =>
<li key={index}>
{person.name}
</li>
)}
</ul>
</div>
)
}
export default GetAllPeople;
question from:
https://stackoverflow.com/questions/65873133/best-way-to-request-unknown-number-of-api-pages-in-useeffect-hook 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…