Reputation: 1538
This is a re-write of a previous post I made since I am able to reproduce the same problem using much simpler example.
I've created a simple app using npx create-react-app. I added logging logic to my App.js file as follows.
import logo from './logo.svg';
import './App.css';
function App() {
console.log("###? App()");
const logStuff = () => {
console.log("###? Logging stuff")
fetch("https://httpbin.org/post", {
method: 'POST',
body: JSON.stringify({error: "hello", message: "there"}),
})
.then(() => console.log('###? useLog() response'))
.catch((error) => {
console.error('###? Failed to send log with error: ' + error);
});
}
return (
<div className="App">
{logStuff()}
<header className="App-header">
<img src={logo} className="App-logo" alt="logo"/>
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
export default App;
When I launch the app I get the following logs:
###? App() App.js:5
###? Logging stuff App.js:8
###? useLog() response App.js:9
###? useLog() response
In the network tab I see the following:
The App() function is called once. The logStuff() function is called once; but in the network console I can see two requests go out to that URL and I don't understand why.
Upvotes: 0
Views: 1216
Reputation: 895
You've put logStuff function in your return statement, which is why you're experiencing this behaviour. Remember as a good practice return statement of a component should only return JSX/Components and should not be used for any calls. If you're running a function inside return statement, it should return JSX/Component.
This is the right way.
import './App.css';
function App() {
console.log("###? App()");
useEffect(() => {
logStuff() //this should be regular practice for side effects
},[]) //useEffect would run once only. If you want to change it on condition then provide other arguments to the array.
const logStuff = () => {
console.log("###? Logging stuff")
fetch("https://httpbin.org/post", {
method: 'POST',
body: JSON.stringify({error: "hello", message: "there"}),
})
.then(() => console.log('###? useLog() response'))
.catch((error) => {
console.error('###? Failed to send log with error: ' + error);
});
}
return (
<div className="App">
// {logStuff()} this was the problem, the function was calling on each render
<header className="App-header">
<img src={logo} className="App-logo" alt="logo"/>
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
export default App;
Upvotes: 1