I am trying to get started with Node.js. I have created a simple page:
'use client';
import React, { useEffect, useState } from 'react';
import axios from 'axios';
function callApi() {
const [data, setData] = useState('');
useEffect(() => {
axios.post('http://localhost:3001/api/data', {firstName: 'Fred', surname: 'Bloggs'}, {headers: {'Content-Type': 'multipart/form-data'}})
.then(response => {
setData(response.data.message);
})
.catch(error => {
console.error(error);
});
}, []);
return (
<div className="App">
<h1>React and Node.js Integration</h1>
<p>Message from the server: {data}</p>
</div>
);
}
export default callApi;
and a simple Node.js endpoint that handles post requests:
const express = require('express');
const app = express();
const port = 3001;
const multer = require('multer');
const upload = multer();
app.post('/api/data', upload.none(), (req, res) => {
const formData = req.body;
console.log('form data', formData);
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'OPTIONS, GET,POST');
res.setHeader('Access-Control-Max-Age', 2592000); // 30 days
const data = "Response from POST request: " + formData.firstName + " " + formData.surname
res.json(data)
});
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
I don’t think this is working properly because (1) Fred Bloggs is printed to the Terminal twice in Node.js even though there is only one call to console.log as shown below:
Also ‘Response from POST request:Fred Bloggs’ is not returned to the client.
3
Answers
You might be seeing "Fred Bloggs" printed twice because your browser could be sending an additional preflight request. When CORS is involved, browsers often send an OPTIONS request before the actual POST request. This preflight request does not contain the form data, but your server may still be logging it.
You can update your Node.js code to handle the OPTIONS request separately and avoid logging it.
You are not sending the response correctly in your res.json call. The res.json() method expects an object, but you are passing a string.
Updated code
Node.js endpoint
The issue you are experiencing with is related React Development mode – not NodeJS itself.
The primary reason for
useEffect
executing twice is the strict mode in React’s development mode. This mode intentionally invokes lifecycle methods and effects multiple times to help identify problems. It’s a feature designed to aid developers, not a bug. For example, it is common to subscribe events inuseEffect
and forget to clean them on unmount, which causes a memory leak. Double invocation in dev mode helps to identify such mistakes at an early stages.It only happens in Dev mode not in Prod build.
It might be confusing at first but I don’t see much problem sending 2 requests in dev mode.
Here is more details explained by React Team. Info
Since React 18, the
Strict mode
provoke api call to be triggered twice to ensure a correct behaviour of your application. You can try disabling it to be sure. In a basic react app, you should find something like :Remove or comment the
StrictMode
component And check again.