In theory the array should be populated continuously and should be reflected in rendering the page but instead it keeps getting overwritten. ending with a list that has only the last added value.
This is a striped down version of what I am trying to obtain.
// Just a function to simulate fetching data from an API
async function getData(id) {
// Simulate Delay
await new Promise((r) => setTimeout(r, id * 1000));
return `Data ${id}`;
}
function App(props) {
const [data, setData] = React.useState("Loading...");
const [arr, setArr] = React.useState([]);
React.useEffect(() => {
getData(0).then(setData);
}, []);
React.useEffect(() => {
if (data && arr.length == 0) {
for (let i = 1; i < 6; i++) {
getData(i).then((resolve) => {
setArr([resolve, ...arr]);
});
}
} else {
setArr([]);
}
}, [data]);
return (
<>
<h3>{data}</h3>
<ul>
{arr.map((item) => (
<li key={item}>{item}</li>
))}
</ul>
</>
);
}
Data 0
Data 0
After research I found that you could pass a function to a setState() in the form of (currentStateValue) => {}. To prevent the data from being called twice due to the second useEffect being fired twice, create another state isFetchingMoreData to check against.
// Just a function to simulate fetching data from an API
async function getData(id) {
// Simulate Delay
await new Promise((r) => setTimeout(r, id * 1000));
return `Data ${id}`;
}
function App(props) {
const [data, setData] = React.useState("Loading...");
const [arr, setArr] = React.useState([]);
const [isFecthingMoreData, setIsFecthingMoreData] = React.useState(false);
React.useEffect(() => {
getData(0).then(setData);
setIsFecthingMoreData(true);
}, []);
React.useEffect(() => {
if (isFecthingMoreData) {
setIsFecthingMoreData(false);
for (let i = 1; i < 6; i++)
getData(i).then((resolve) => {
setArr((prev )=>[...prev, resolve]);
});
} else {
setArr([]);
}
}, [data]);
return (
<>
<h3>{data}</h3>
<ul>
{arr.map((item) => (
<li key={item}>{item}</li>
))}
</ul>
</>
);
}