In this article, we will look at how to connect React with the Node Js server. React will be our front-end library and Node Js will serve as the backend server.

Let’s begin by creating a node Js server. We will be using express which will help us create a web server quickly. I will create an empty folder that will have all the Node Js code in it.

mkdir react-node-app

Navigate to the new folder react-node-app and run the npm init command.

cd react-node-app
npm init

This will create a package.json file which will help us install all the dependencies for the project.

Next, we will install the express framework using the following command:

npm i express

We will also install the Nodemon tool that automatically restarts the server when the files change.

npm i nodemon -D

Let’s add the Nodemon configuration in the package.json file. Within the scripts key add the following code:

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "nodemon server.js"
  }

Since we are using server.js file let’s change the “main” value from index.js to server.js.Now, the entire file should look something like this:

{
  "name": "react-node-app",
  "version": "1.0.0",
  "description": "",
  "main": "server.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "nodemon server.js"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.18.2"
  },
  "devDependencies": {
    "nodemon": "^2.0.20"
  }
}

Next, we will create a server.js file that will contain the code for our backend API.

touch server.js

Open up the server.js and initialize the express server.

const express = require('express')

const app = express()

After this, we will create a route for the API which will have the URL /api. This will be a simple get request which will provide a basic JSON response containing a list of products(hardcoded).

app.get("/api", (req, res) => {
  res.json({
    products: [
      { id: 1, name: "Product-1" },
      { id: 2, name: "Product-2" },
      { id: 3, name: "Product-3" },
      { id: 4, name: "Product-4" },
    ],
  });
});

Let’s run the node server on port 4000.

app.listen(4000, () => {console.log('server started....port: 4000')});

You can now access the API using the URL http://localhost:4000/api

react-node-api

We are now ready with our backend API. We will keep the server running on port 4000.

The next step is to create a React app and call the Node Js API.

Open a new tab in the terminal and navigate to the react-node-app project folder. Now run the npx create-react-app command to create the react application. I will name the react app as client.

npx create-react-app client

This will create a client folder that will contain the react app code. Navigate to the client folder and run the react server to start the react application. By default, it will start the server on port 3000.

cd client
npm start

react-default-node

We will be using App.js file to display the API content so let’s delete all the content from and rewrite the code as per our requirement.

// react-node-app/src/App.js

function App() {
  return (
    <div>
      <h1>Hello there!</h1>
    </div>
  );
}

export default App;

hello-react

We will be using useEffect() to fetch the data from the Node Js server and display the list of products on the first load. Let’s also define a variable called products to hold the data using useState().

import { useState, useEffect } from "react";

function App() {

  const [products, setProducts] = useState([]);

  useEffect(() => {
    fetch("http://localhost:4000/api")
      .then((response) => response.json())
      .then((data) => setProducts(data.products));
  }, []);

  return (
    <div>
      <h1>Hello there!</h1>
    </div>
  );
}

export default App;

We are calling the http://localhost:4000/api from the useEffect using the fetch method. The response returned from the API is then assigned to the products variable. Now, let’s make changes in UI to display the products obtained from the API. We will use the map() method to loop through the products and display the product names.

{products.map((product) => (
        <div key={product.id}>{product.name}</div>
))}

Now, the entire file should look like this:

import { useState, useEffect } from "react";

function App() {
  const [products, setProducts] = useState([]);
  useEffect(() => {
    fetch("http://localhost:4000/api")
      .then((response) => response.json())
      .then((data) => setProducts(data.products));
  }, []);

  return (
    <div>
      <h1>Hello there!</h1>
      {products.map((product) => (
        <div key={product.id}>{product.name}</div>
      ))}
    </div>
  );
}

export default App;

This however will throw an error Access to fetch at '[http://localhost:4000/api](http://localhost:4000/api)' from origin '[http://localhost:3000](http://localhost:3000/)' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

This error occurs because we are trying to access the backend API which is at port 4000 from the client-server running at port 3000. There is a mismatch between the URLs and the browser complains that the same origin policy disallows reading from the remote server at http://localhost:4000

cors-react-node-error

To solve this issue we need to enable CORS(Cross-Origin Resource Sharing) at the server(NodeJs) end. Let’s first install the cors package provided by Npm.

npm i cors

Next, initialise cors in the server.js file and allow the URL (http://localhost:3000) to access the Node API.

const cors = require('cors');

app.use(cors({
    origin: 'http://localhost:3000'
}));

The entire server.js file should now look like this:

const express = require("express");

const app = express();

const cors = require('cors');

app.use(cors({
    origin: 'http://localhost:3000'
}));

app.get("/api", (req, res) => {
  res.json({
    products: [
      { id: 1, name: "Product-1" },
      { id: 2, name: "Product-2" },
      { id: 3, name: "Product-3" },
      { id: 4, name: "Product-4" },
    ],
  });
});

app.listen(4000, () => {
  console.log("server started....port: 4000");
});

Restart the node server and the page at http://localhost:3000 should display the content from the API.

integrate-react-nodejs

That is it!