Reputation: 4413
If I run the code below, I get an infinite loop (as indicated in the console log). I think this happens because my useState callback (setEvents) causes a re-render which causes the function App to be re-run, which then re-fetches the data, calls my useState callback again and so on. This code is based on numerous examples I've seen online - what am I doing wrong?
import React, {useState, useEffect} from 'react';
import {BrowserRouter as Router, Route} from "react-router-dom";
import EventMonitorRoute from './routes/event-monitor';
import ReactDOM from 'react-dom';
function App() {
console.log('Running App'); // DEBUG
let basename = (window.location.hostname === 'localhost') ? '/' : '/event_monitor';
let apiURL = 'https://example-api.com';
const [events, setEvents] = useState(null);
async function fetchData(apiURL) {
console.log('fetching data'); // DEBUG
const response = await fetch(apiURL);
const json = await response.json();
setEvents(json);
}
useEffect(() => {
fetchData(apiURL)
});
return (
<Router basename={basename}>
<div id="app-container-inner">
<Route exact path="/" render={(props) => <EventMonitorRoute events={events} {...props}/>}/>
</div>
</Router>
);
}
ReactDOM.render(
<App/>,
document.getElementById('app-container')
);
Upvotes: 0
Views: 774
Reputation: 21317
Move the declaration inside the effect and pass an empty array as second argument:
console.log('Running App'); // DEBUG
useEffect(() => {
let basename = (window.location.hostname === 'localhost') ? '/' : '/event_monitor';
let apiURL = 'https://example-api.com';
const [events, setEvents] = useState(null);
async function fetchData(apiURL) {
console.log('fetching data'); // DEBUG
const response = await fetch(apiURL);
const json = await response.json();
setEvents(json);
}
fetchData(apiURL)
}, []);
Upvotes: 1