Connect Frontend and Backend in React to create dynamic and interactive user interfaces. React, a popular JavaScript library for building user interfaces, relies on the backend to manage data and handle business logic. To integrate the two, you need to understand technologies like RESTful APIs, AJAX, and state management.
In this article, we will explore the essential steps to connect Frontend and Backend in React and receive data from the backend and display it in the frontend.
Important factors to consider before beginning
Before diving into the tutorial on connecting the back-end and front-end, there are a few things to keep in mind. This tutorial is not suitable for beginners, so a basic understanding of React and Node.js is necessary to follow along.
For this tutorial, we’ll be building a small application where we display data after fetching from backend and we can also add more data to our existing data using React.js for our frontend and Express.js for our backend. Before we dive into the code, we need to install a few libraries to get started. But first, let’s discuss how we should structure our folders for this project.
We recommend organizing your project into separate folders for the frontend and the backend. Within the backend folder, you can create subfolders for different parts of your application, such as “config” for configuration files, “controllers” for handling requests and responses, “models” for defining your database schemas, and “routes” for defining your API endpoints.
Similarly, within the frontend folder, you can have subfolders for “components” and “pages”, where you keep your React components and different pages of your application respectively. You can also have a “utils” folder for any utility functions you might write.
Once we have our folder structure in place, we can start installing the necessary libraries and building our application. Let’s get started!
Also read, How to select only one element of a map() in React
Folder Setup for Backend
To make this tutorial more accessible to beginners, we’ll be creating a simple route and controller in just one file – our index.js file.
Typically, for a larger application, you would want to separate your routes and controllers into different files to keep your code organized and maintainable. However, for the sake of simplicity and brevity, we’ll be using this approach today.
Typically, for a larger application, you would want to separate your routes and controllers into different files to keep your code organized and maintainable. However, for the sake of simplicity and brevity, we’ll be using this approach today.
So in our index.js file, we’ll define a simple route and set up a corresponding controller function to handle requests to that route. This will give you a sense of how routes and controllers work together in Express.js, which will come in handy as you start building more complex applications.
.
└── Backend/
├── node modules
├── database.js
├── index.js
├── package-lock.json
└── package.json
Folder Setup for Frontend
Again, to make this tutorial more accessible to beginners, we’ll write all our functionality to receive and display the data we received from the backend into our UI in our App.js file.
.
└── Frontend/
├── node modules
├── public
├── src/
│ ├── app.css
│ ├── app.js
│ ├── index.css
│ └── index.js
├── package-lock.json
└── package.json
Also read, An Artificial Discussion Regarding Artificial Intelligence
Libraries we need for the Backend
To begin, let us initialize a package.json file to our backend folder. To do you need to open the terminal in your backend folder and in the terminal you need to type the following command,
npm init
You can fill in all the details as you like or just hit enter throughout the whole process, this will create a package.json file. In your package.json file under “main”: ”index.js”
, add “type”:”module”
line, so that you can now use the import command, just like you do in react.
To get started with an Express.js backend, you will need to install a few dependencies. Here are the most common ones to get started:
- Express: The main library for building web applications with Node.js and Express.
- body-parser: Middleware that allows you to access form data, JSON payloads, and URL parameters under the
req.body
property. - cors: This library provides middleware for handling Cross-Origin Resource Sharing (CORS) issues. This is particularly helpful if you’re building an API and you need to handle requests from different domains.
npm install express body-parser cors
Libraries we need for the Frontend
For our Frontend, we only need to install React library, first open the terminal with frontend folder, and then in the terminal write,
npx create-react-app ./
This will install React app with all the necessary files and dependencies to get started with React development.
Also read, Simple tutorial on React authentication with redux + Example
Setting up the Backend(Express Js)
First, we will set up our backend to have two endpoints. One endpoint will be responsible for receiving data from the frontend and updating the backend database, and the other endpoint will be responsible for sending data from the backend to the frontend.
Setting up the Node Server
Open your index.js file and write a few lines of codes mentioned below:
import express from "express";
const app = express();
app.get("/", (req, res) => {
res.status(200).json("Hello World");
});
let port = 8000;
app.listen(port, () => {
console.log(`Port is running at ${port}`);
});
In your terminal run the following command,
node index.js
You would able to see the console message and if you open your browser and go to localhost:8000
, you would see the below message, which indicates the node server is successfully running.
Creating Endpoints
Next, we will create two endpoints for our backend. To demonstrate how they work, we will be using a mock database with some pre-defined values. The first endpoint will send the data through to the frontend, and the second endpoint will allow updating of the database with new data. In our database.js file, we will add array-objects that will act as our database, Our code would look like this,
let data = [
{
id: 1,
name: "Guy Hawkins",
age: 27,
country: "Haiti",
},
{
id: 2,
name: "Jane Cooper",
age: 19,
country: "Monaco",
},
{
id: 3,
name: "Jacob Jones",
age: 32,
country: "Poland",
},
{
id: 4,
name: "Cody Fishers",
age: 29,
country: "Mexico",
},
{
id: 5,
name: "Brooklyn Simmons",
age: 25,
country: "USA",
},
{
id: 6,
name: "Esther Howard",
age: 26,
country: "Spain",
},
{
id: 7,
name: "Annette Black",
age: 22,
country: "UK",
},
{
id: 8,
name: "Marvin McKinney",
age: 30,
country: "Germany",
},
];
export default data;
Also, Before we move forward with our endpoints, first we need to set up our cors and body-parser libraries, Our code would look like this,
import express from "express";
import bodyParser from "body-parser";
import cors from "cors";
import database from "./database.js";
const app = express();
/* To handle the HTTP Methods Body Parser is used, Generally used to extract the entire body portion of an incoming request stream and exposes it on req.body
*/
// support parsing of application/json type post data
app.use(bodyParser.json());
//support parsing of application/x-www-form-urlencoded post data
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cors());
app.get("/", (req, res) => {
res.status(200).json('Hello World');
});
let port = 8000;
app.listen(port, () => {
console.log(`Port is running at ${port}`);
});
Creating Get endpoint
In our default app.get
code, we will edit and instead of hello-world, we would simply send our database, code would look like this
app.get("/", (req, res) => {
res.status(200).json(database);
});
Also read, Easy tutorial to build React Autosuggest from scratch
Creating Put endpoint
In order to receive and update our existing mock database we will use the ‘put’ method, in which we will first update and then send back our database with newly added data, code would look like this,
app.put("/add", (req, res) => {
database.push({
id: database[database.length - 1].id + 1,
name: req.body.name,
age: req.body.age,
country: req.body.country,
});
try {
res.status(200).json(database);
} catch (error) {
res.status(404).json({ message: error.message });
}
});
After adding all the above codes, our index.js would look like the below and then we would simply re-run our node server,
import express from "express";
import bodyParser from "body-parser";
import cors from "cors";
import database from "./database.js";
const app = express();
/* To handle the HTTP Methods Body Parser
is used, Generally used to extract the
entire body portion of an incoming
request stream and exposes it on req.body
*/
// support parsing of application/json type post data
app.use(bodyParser.json());
//support parsing of application/x-www-form-urlencoded post data
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cors());
app.get("/", (req, res) => {
res.status(200).json(database);
});
app.put("/add", (req, res) => {
database.push({
id: database[database.length - 1].id + 1,
name: req.body.name,
age: req.body.age,
country: req.body.country,
});
try {
res.status(200).json(database);
} catch (error) {
res.status(404).json({ message: error.message });
}
});
let port = 8000;
app.listen(port, () => {
console.log(`Port is running at ${port}`);
});
Also read, How Does React Js works | Detail Explanation on Virtual DOM
Setting up the Frontend(React)
We will now shift our focus to the frontend of our blog. To keep things concise, I will not be discussing the basic structure and workings of CSS. Instead, I will focus solely on how you can add an API to your frontend.
Setting up our App’s Basic UI Structure and CSS
In our app js file, Replace the contents of the app.js file with the following JavaScript code,
import "./App.css";
import { useState, useEffect } from "react";
function App() {
const [name, setName] = useState("");
const [age, setAge] = useState("");
const [country, setCountry] = useState("");
const [data, setData] = useState([]);
const handleSubmit = (event) => {
event.preventDefault();
};
return (
<div className="App">
<div className="input-area">
<h2>Add More Data</h2>
<div className="form-area">
<form onSubmit={handleSubmit}>
<div className="input-1">
<span>Add Name</span>
<input
value={name}
placeholder="Enter Person Name..."
onChange={(e) => setName(e.target.value)}
/>
</div>
<div className="input-2">
<span>Add Age</span>
<input
value={age}
placeholder="Enter Person Age.."
onChange={(e) => setAge(e.target.value)}
/>
</div>
<div className="input-3">
<span>Add Country</span>
<input
value={country}
placeholder="Enter Person Country..."
onChange={(e) => setCountry(e.target.value)}
/>
</div>
<button type="submit">Save Data</button>
</form>
</div>
</div>
<div className="display-area">
<h2>Data From Api Displayed down below</h2>
<table>
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Age</th>
<th>Country</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
);
}
export default App;
And in our Index.css file, add the following CSS code,
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #f8f8f8;
}
.App {
width: 500px;
padding: 20px 30px 20px 20px;
background-color: #fff;
border-radius: 24px;
box-shadow: 0 60px 40px rgb(0 0 0/ 10%);
}
.input-area {
padding-bottom: 20px;
border-bottom: 1px solid darkgray;
}
h2 {
font-size: 18px;
}
input {
border: none;
background: #f2f2f5;
padding: 10px 12px;
width: 300px;
}
.input-1,
.input-2,
.input-3 {
display: flex;
align-items: center;
margin: 20px 0;
}
.input-1 {
gap: 52px;
}
.input-2 {
gap: 65px;
}
.input-3 {
gap: 36px;
}
button {
border: none;
padding: 10px 25px;
background: #5563c1;
color: white;
}
table {
width: 100%;
}
table,
th,
td {
border: 1px solid black;
border-collapse: collapse;
}
td {
text-align: left;
padding: 2px 5px;
}
Also read, A simple React Hook Form Validation with Formik and Yup
Adding Get endpoint
First, we will add javascript code to display data that we are getting from the backend, add the following code,
useEffect(() => {
fetch("http://localhost:8000/")
.then((response) => response.json())
.then((item) => setData(item));
}, data);
In the above code, with the help of the fetch function, we would receive the JSON data from the backend which we will store, with the help of setData, useState hook. And because we are using the fetch function inside our useEffect
hook, as data updates, it will re-render our file. And in order to display our backend data, inside our <tbody></tbody>, we will add the following code,
<tbody>
{data.map((item) => {
return (
<tr key={item.id}>
<td>{item.id}</td>
<td>{item.name}</td>
<td>{item.age}</td>
<td>{item.country}</td>
</tr>
);
})}
</tbody>
Once you save the code, you would see the below UI,
Adding Put endpoint
Now if we want to send and update some new data to our database, we will add the following code inside our handleSubmit function,
const handleSubmit = (event) => {
event.preventDefault();
fetch("http://localhost:8000/add", {
method: "PUT", // or 'PUT'
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({name,age,country}),
})
.then((response) => response.json())
.then((data) => {
setData(data);
})
.catch((error) => {
console.error("Error:", error);
});
};
When we fill in the input section and click on submit button, with help of the fetch function it would convert our data into JSON form and send it to the backend, then we will receive updated data with our recently added input and then we will update our data hook with the help of setData.
Also read, How to add/remove input fields dynamically with Reactjs
Note– Please note that in a typical development process, it would be advisable to include some debug functionality to verify that the user has inputted the correct data upon submission. However, to keep this tutorial brief, such functionality has been omitted. As a task, I encourage you to add this feature on your own.
Because we have added a data hook in our useEffect function, whenever data hook values change, React will re-render the whole page and finally, we get to see our data in the UI.
Our Final Code will look like something below,
import logo from "./logo.svg";
import "./App.css";
import { useState, useEffect } from "react";
function App() {
const [name, setName] = useState("");
const [age, setAge] = useState("");
const [country, setCountry] = useState("");
const [data, setData] = useState([]);
const handleSubmit = (event) => {
event.preventDefault();
fetch("http://localhost:8000/add", {
method: "PUT", // or 'PUT'
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({name,age,country}),
})
.then((response) => response.json())
.then((data) => {
setData(data);
})
.catch((error) => {
console.error("Error:", error);
});
};
useEffect(() => {
fetch("http://localhost:8000/")
.then((response) => response.json())
.then((item) => setData(item));
}, data);
return (
<div className="App">
<div className="input-area">
<h2>Add More Data</h2>
<div className="form-area">
<form onSubmit={handleSubmit}>
<div className="input-1">
<span>Add Name</span>
<input
value={name}
placeholder="Enter Person Name..."
onChange={(e) => setName(e.target.value)}
/>
</div>
<div className="input-2">
<span>Add Age</span>
<input
value={age}
placeholder="Enter Person Age.."
onChange={(e) => setAge(e.target.value)}
/>
</div>
<div className="input-3">
<span>Add Country</span>
<input
value={country}
placeholder="Enter Person Country..."
onChange={(e) => setCountry(e.target.value)}
/>
</div>
<button type="submit">Save Data</button>
</form>
</div>
</div>
<div className="display-area">
<h2>Data From Api Displayed down below</h2>
<table>
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Age</th>
<th>Country</th>
</tr>
</thead>
<tbody>
{data.map((item) => {
return (
<tr key={item.id}>
<td>{item.id}</td>
<td>{item.name}</td>
<td>{item.age}</td>
<td>{item.country}</td>
</tr>
);
})}
</tbody>
</table>
</div>
</div>
);
}
export default App;
and our UI would look like something below,
Also read, Add Redux to your React app in 6 Simple Steps
Final Words
Thank you for taking the time to read my article. I hope you found it helpful and enjoyable. If so, please consider sharing it with your friends and colleagues. Additionally, feel free to bookmark this website for access to more straightforward and engaging tutorials on a variety of topics related to react, javascript, data structure and algorithm, java, and programming.