I am working with Strapi, which is built on React. I have a custom page which I try to show some data. However, when I open that page, the network tab and the debugger on terminal, show that a request is triggered in a loop. Since I am new to React, I am not sure what the problem is, but my guess is something with the state
.
const { pathType, id } = useParams();
const [data, setData] = useState([]);
const getData = () => request(`/${pathType}/${id}`, {method: 'GET'});
useEffect(() => {
getData().then(response => {
return response;
}).then(setData).catch(e => console.log(e));
});
return (
<>
<Container className="container-fluid">
<div className="row">
{JSON.stringify(data, null, 2)}
</div>
</Container>
</>
);
And here is part of the debugger where shows the request from the getData()
[2020-08-31T10:33:30.644Z] debug OPTIONS /hostings/40 (1 ms) 204
[2020-08-31T10:33:30.942Z] debug GET /hostings/40 (297 ms) 200
[2020-08-31T10:33:30.949Z] debug OPTIONS /hostings/40 (0 ms) 204
[2020-08-31T10:33:31.241Z] debug GET /hostings/40 (291 ms) 200
....
Referring to react documentation on useEffect
Data fetching, setting up a subscription, and manually changing the DOM in React components are all examples of side effects.
Simply put: in your case, useEffect
will be called every time you change the DOM through using setData
Now you want your useEffect
to only setData
only when data
is empty. To do that you should add a condition to the useEffect
as follows:
useEffect(() => {
if (data.lenght !== 0) return
getData().then(response => {
return response;
}).then(setData).catch(e => console.log(e));
});
This will ensure that you setData
only when data
is empty.
You can check Why effects run on each update
And "quoting from react docs"
If you want to run an effect and clean it up only once (on mount and unmount), you can pass an empty array ([]) as a second argument.
So useEffect
should look like
useEffect(() => {
...
}, []);