Reputation: 25
I would like to store the data of a response into an array for reuse. I am using Axios for this. The issue I receive is that when I push into the array, it loops getBoroughAndId() and keeps pushing into the array. I can tell because I get a console.log() response where it keeps telling me I am making too many requests. Any advice? Thanks.
Edit: After taking another gander, I think the issue is that the id is always changing when running getBoroughAndId. I'm not sure how to stop this.
import React, { useEffect, useState } from 'react';
import { airtableApi } from '../services/api/airtable';
import { BoroughDay, BoroughGroup } from '../types/api';
const IndexPage = () => {
const [boroughs, setBoroughs] = useState<BoroughDay[]>([]);
const [boroughGroups, setBoroughGroups] = useState<BoroughGroup[]>([]);
const getBoroughsAndDays = () => {
airtableApi
.getBoroughsAndDays()
.then((response) => {
setBoroughs(response);
})
.catch(() => { });
};
const getBoroughAndId = (id: string) => {
airtableApi
.getBoroughAndId(id)
.then((response) => {
console.log(response);
setBoroughGroups(arr => [...arr, response])
return response;
})
.catch(() => { });
}
useEffect(() => {
getBoroughsAndDays()
}, [boroughGroups])
return (
<>
{boroughs.map((data) => {
getBoroughAndId(data.id);
})}
</>
)
}
export default IndexPage
Here is my corrected code. It works a lot better now, with less nonsense and everything being done in the first function.
import React, { useEffect, useState } from 'react';
import { airtableApi } from '../services/api/airtable';
import { BoroughDay, BoroughGroup } from '../types/api';
const IndexPage = () => {
const [boroughs, setBoroughs] = useState<BoroughDay[]>([]);
const [boroughGroups, setBoroughGroups] = useState<BoroughGroup[]>([]);
const getBoroughsDays = () => {
airtableApi
.getBoroughsAndDays()
.then((response) => {
setBoroughs(response.records);
response.records.map((data) => {
setBoroughGroups(arr => [...arr, {id: data.id, "Borough": data.fields["Borough"]}])
})
})
.catch(() => { })
}
useEffect(() => {
getBoroughsDays();
}, [])
return (
<>
{boroughGroups.map(data => <div>{data.id} {data.Borough}</div>)}
</>
)
}
export default IndexPage
Upvotes: 1
Views: 705
Reputation: 116
In order to tell you the mistake you are committing, I will tell you the whole flow of your program.
Note: boroughGroups in dependency array in useEffect is causing an infinite loop
This function (getBoroughsAndDays()) will update the value of boroughs(using setBoroughs)
Now since the state updated the function will re render, hence output will be shown on the screen
Now observe, here you are calling "getBoroughAndId(data.id)" function (inside map function), which is updating the value of boroughGroups(using setBoroughGroups)
Now since the value of boroughGroups have changed, the useEffect method will be called, which will again trigger the "getBoroughsandDays()" function, repeating the whole process again, so that is the reason, it is creating infinite loop.
Note: When any value inside dependency array changes useEffect will be called.
Solution: I don't know what functionality you want to achieve but remove "boroughGroups" dependency from useEffect (In this way it will behave like componentDidMount).
Upvotes: 1
Reputation: 315
You have a useEffect
hook that updates state: boroughs
whenever value of state: boroughGroups
changes.
In the return statement, you iterate through boroughs
and update boroughGroups
.
Back to the first statement.
To stop this infinite loop, stop updating boroughGroups
, that triggers useEffect
everytime.
useEffect(() => {getBoroughsAndDays()}, []);
Upvotes: 0