Easiest Way to Connect a React Frontend with Node.js

‌‌‌‌‌‌
Zero Equals False
Published in
5 min readJul 20, 2020

When I first learned to use React, a frontend library for JavaScript, I was hyped. Managing state with React hooks and building nice looking web apps were awesome. However, I didn’t know how to connect that to a Node.js backend. All the tutorials I read and watched had too many unnecessary dependencies and complicated nuances. That’s why in this tutorial, we will be sticking to the bare basics.

I’m going to assume you already know a bit of Node.js and React.js for this tutorial. If not, don’t worry, I’ll explain things as we go. In this tutorial, we will be creating a simple quote generator web app.

1. The Folder Setup

First, create a folder in your working directory for the app. Then, inside that directory, make the folder for my backend in Node.js. I will name mine “backend” for simplicity's sake. Then, install express for handling routes. For getting my quotes, I will use the inspirational-quotes npm package.

$ mkdir quotes-app
$ cd quotes-app
$ mkdir backend
$ cd backend
$ npm init -y
$ npm install express inspirational-quotes

Now let’s write some code.

2. The Backend

Create an app.js file and set it up like so:

const Quote = require('inspirational-quotes');console.log(Quote.getQuote());

If we run this, we will see that we get a JavaScript object containing two keys: text and author. Let’s finish setting up the rest of our express/Node backend. Instead of printing the JavaScript object to console, I will send it instead when the home route is accessed (like so):

const express = require("express");
const Quote = require('inspirational-quotes');
const app = express();app.get("/", function(req, res) {
res.send(Quote.getQuote());
});
let port = process.env.PORT;
if(port == null || port == "") {
port = 5000;
}
app.listen(port, function() {
console.log("Server started successfully");
});

Don’t worry about process.env.port for now, those of you who have used Heroku or deployed apps should find that familiar, however. From here, if we navigate over to our localhost, we should find a JSON with what we previously printed to console.

If you’re wondering how I get such beautifully formatted JSON on Chrome, check out JSON Viewer Awesome.

Cool, we’re done with the backend. Wait what, it was that easy??? Yep, we’re really done.

3. The Frontend

Now let’s back out of our current directory, into the outer folder and create our react app. I’m going to call mine “frontend” just for simplicity’s sake, once again. Once that’s done, navigate into the “frontend” directory.

$ cd ..
$ npx create-react-app frontend
$ cd frontend

Inside the “src” directory, create a file called ”Quotes.jsx”. Populate it with this code: which just gives a button. For now, this button won’t do anything.

import React, {useState} from "react";function Quotes() {
const [text, setText] = useState("");
const [author, setAuthor] = useState("");
return (
<div>
<button>
Generate Quote
</button>
<h1>{text}</h1>
<h3>{"-" + author}</h3>
</div>
)
}
export default Quotes;

Then, in the App.js, import this component and use it. I’ve removed some extra stuff that was auto-generated.

import React from 'react';
import logo from './logo.svg';
import './App.css';
import Quotes from "./Quotes";
function App() {
return (
<div className="App">
<header className="App-header">
<Quotes />
</header>
</div>
);
}
export default App;

At this point, running the app will simply give you a button and a “-”. The next step is where the magic happens: we will combine the frontend and the backend.

Inside your package.json file, insert this line of code under the “private: true”. If you did not use 5000 as your backend port, make it whichever port you chose. However, this port MUST be different than 3000, since that is what our React app uses.

"proxy": "http://localhost:5000",

Now, install a dependency called axios. If you aren’t familiar with axios, don’t worry. We’ll write a few lines of code with it and that’s it. Axios just lets us make HTTP requests to our backend, and it works similarly to express.

import React, {useState} from "react";
import axios from "axios";
function Quotes() {
const [text, setText] = useState("");
const [author, setAuthor] = useState("");
function getQuote() {
axios.get("http://localhost:5000/", { crossdomain: true }).then(response => {
setText(response.data.text);
setAuthor(response.data.author);
});
}
return (
<div>
<button onClick={getQuote}>
Generate Quote
</button>
<h1>{text}</h1>
<h3>{"-" + author}</h3>
</div>
)
}
export default Quotes;

At this point, when the button is clicked, it triggers our function “getQuote”, which then uses axios to get the information we wanted at route “/” . The information we want, our JavaScript object, is given to us with response.data, so if you printed it to console it would look identical to what we printed in the beginning of this tutorial.

Note: if you run your React app and the button is not doing anything, add this code to your backend app.js right above the app.get(“/”):

app.use(function(req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
next();
});

Sometimes axios gets blocked by CORS, so we need to bypass this using the above code.

Your final result should look like this.

If anything doesn’t match up, be sure to check out the code, which is posted on GitHub. The frontend repo is here, and the backend repo is here.

Note: to deploy this app, you should deploy the backend separately. Then, use that link and replace the localhost link when using Axios. The frontend should then be deployed separately as well. You can do this easily with Github pages.

If this helped, please give me a clap! If you guys want to see a tutorial on deploying this app, let me know in the comments. :) If you want to deploy the frontend and have a custom URL for free, check out my article on it:

Check out LinkedOut, my Chrome Extension that will boost your productivity on LinkedIn and save your mental health.

--

--