Creating React Redux Express Full Stack Application Part-I
Introduction
In this post we will learn how to create a full stack application using React as frontend and Express as backend. We will use Proxy to forward the API calls from React layer to Express layer.
To give you a brief introduction, React Js is one of the most popular and widely used frontend Javascript library(not a framework) React JS. It was developed by Facebook and its component-based library lets you build high quality user-interfaces for web apps.
Node.js shines in real-time web applications development. It offers the developers the luxury of writing the server-side applications in the JavaScript.
The main idea of Node.js is to use non-blocking, event-driven I/O to remain lightweight and efficient in the face of data-intensive real-time applications that run across distributed devices. It operates on a single-thread, allowing it to support tens of thousands of concurrent connections (held in the event loop).
Pre-requisites
- Basic knowledge of HTML, CSS, ES6 syntax & features and JavaScript programming
- Basic understanding of DOM
- Node.js and npm installed globally
Once Node is installed, we will follow below steps to create the application.
Creating React Frontend Application
Create a project using create-react-app
npx create-react-app react-express-app
Create a /client
directory under react-express-app directory and move all the React boilerplate code created by create-react-app
to this new client directory.
To start newly created react application, go to client folder and run command
npm start
You can see application running on http://localhost:3000/
Creating Node.js Express Backend Server
Create a package.json
file inside the root directory (react-express-app
) and copy the following contents:
{
"name": "react-express-app",
"version": "1.0.0",
"scripts": {
"client": "npm start --prefix client",
"server": "node server.js",
"start": "concurrently \"npm run server\" \"npm run client\""
},
"dependencies": {
"body-parser": "^1.19.0",
"cors" : "^2.8.5",
"express": "^4.17.1"
},
"devDependencies": {
"concurrently": "^5.3.0"
}
}
Notice I am using concurrently
to run the React app and Server at the same time.
Create a server.js
file and copy the following contents:
const express = require('express');
const bodyParser = require('body-parser');const app = express();
const port = process.env.PORT || 5000;app.use(bodyParser.json());app.get('/api/hello', (req, res) => {
res.send({ express: 'Hello From Express' });
});app.post('/api/data', (req, res) => {
console.log(req.body);
res.send(
`I received your POST request. This is what you sent me: ${req.body.post}`,
);
});app.listen(port, () => console.log(`Listening on port ${port}`));
This is a simple Express server that will run on port 5000 and have two API routes: GET
- /api/hello
, and POST
-/api/data
.
At this point you can run the Express server with the following command (still inside the root directory (react-express-app
)):
1. npm install
2. node server.js
npm install (to install all dependencies given in package.json) and node server.js to start Node express server.
Now navigate to http://localhost:5000/api/hello
, and you will get the following:
Configure Proxy
Proxy enables react client to talk to Express backend.
Now navigate to React app under directory client
and add following line to the package.json
file created by create-react-app
.
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"proxy": "http://localhost:5000/"
The key to using an Express back-end server with a project created with create-react-app
is to use a proxy. This tells the Web-pack development server to proxy our API requests to our API server, given that our Express server is running on localhost:5000
.
Now modify ./client/src/App.js
to call our Express API Back-end.
import React, { Component } from 'react';import logo from './logo.svg';import './App.css';class App extends Component {
state = {
response: '',
post: '',
responseToPost: '',
};
componentDidMount() {
this.callApi()
.then(res => this.setState({ response: res.express }))
.catch(err => console.log(err));
}
callApi = async () => {
const response = await fetch('/api/hello');
const body = await response.json();
if (response.status !== 200) throw Error(body.message);
return body;
};
handleSubmit = async e => {
e.preventDefault();
const response = await fetch('/api/data', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ post: this.state.post }),
});
const body = await response.text();
this.setState({ responseToPost: body });
};
render() {
return (
<div className="App">
<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>
<p>{this.state.response}</p>
<form onSubmit={this.handleSubmit}>
<p>
<strong>Post to Server:</strong>
</p>
<input
type="text"
value={this.state.post}
onChange={e => this.setState({ post: e.target.value })}
/>
<button type="submit">Submit</button>
</form>
<p style={{color : 'blue'}}><b>{this.state.responseToPost}</b></p></div>
);
}
}export default App;
We create callApi
method to interact with our GET
Express API route, then we call this method in componentDidMount
and finally set the state to the API response, which will be Hello From Express.
Notice we didn’t use a fully qualified URL http://localhost:5000/api/hello
to call our API, even though our React app runs on a different port (3000). This is because of the proxy
line we added to the package.json
file earlier.
We have a form with a single input. When submitted calls handleSubmit
, which in turn calls our POST
Express API route then saves the response to state and displays a message to the user: I received your POST request. This is what you sent me: [message from input].
Now open ./client/src/App.css
and modify .App-header
class as follows (changes in bold)
.App-header {
...
min-height: 50%;
...
padding-bottom: 10px;
}
Running the App
If you still have the server running, go ahead and stop it by pressing Ctrl+C in your terminal.
From the project root (react-express-app) directory run the following:
npm start
This will launch the React app and run the server at the same time.
Now navigate to http://localhost:3000
and you will hit the React app displaying the message coming from our GET
Express route.
Get the full source code on GitHub Repository
Conclusion
In this post we learnt how to create a full stack application using React Js as frontend and Express Js as backend using proxy.
Connecting React frontend to Node Express backend using Redux
Redux is a pattern and library for managing and updating application state, using events called “actions”. It serves as a centralised store for state that needs to be used across your entire application, with rules ensuring that the state can only be updated in a predictable fashion.
Steps to integrate Redux with react-Express application is explained in detail in next post.
Thank you for reading. Happy coding!