React MERN Stack CRUD App Tutorial Last updated on August 11, 2020 by Digamber

build React CRUD web application from scratch. Along with that, we will learn how to set up a Node server and create REST APIs using Node and Express.js. React MERN Stack Example Today, I am going to teach you how tofrom scratch. Along with that, we will learn how to set up a Node server and create REST APIs using Node and Express.js. In this MERN stack tutorial, we will create a basic Student app from starting to finish. This app will allow us to create student, show students list, update student, and delete a student from the MongoDB database. [embedyt] https://www.youtube.com/watch?v=d3lhJa9sTFs[/embedyt] Before we move further let’s understand What is MERN stack? MERN Stack stands for MongoDB, Express, React, Node.js and this combined stack is known as MERN stack. Stack Detail MongoDB A document-oriented database programme based on NoSQL. Express It’s a robust Node.js web application framework that helps in creating powerful REST APIs. React A JavaScript library used to create beautiful and interactive user interfaces developed by Facebook and the community of individual developers. Node It’s a JavaScript runtime environment built on Google Chrome’s V8 engine, and it compiles js at the runtime. Tutorial Objective Setting up React project

Creating components in React

Building and working with React routers

Working with React-Bootstrap

Getting started with React forms

Consuming REST APIs in React app

Getting started with Create, Read, Update and Delete in React

Setting up a Node and Express server

MongoDB set up in MERN stack project

Creating REST APIs using Express.js

Making HTTP requests with React Axios library

Prerequisites Before getting started with this tutorial, you must be aware of the fundamentals of React.js and HTML, CSS, JavaScript, TypeScript, or ES6. Check out React’s official website to know more about its features, central concepts, and API reference here. In order to build MERN Stack web application, you must have Node.js installed on your system. Ignore this step if Node is already installed otherwise follow this step by step written article on how to install Node.js? Once the Node is installed run below cmd to check the Node.js version: node -v

Create React Application Let’s start building the React project with create-react-app (CRA). npx create-react-app react-mernstack-crud Get inside the React project folder: cd react-mernstack-crud To start the React MERN Stack project, run following command: npm start This command opens the React project on the following URL: localhost:3000 Once the React is installed successfully, then you can verify the React version in package.json file. "dependencies" : { "react" : "^16.9.0" , "react-dom" : "^16.9.0" , } Now, you are all set to build the React CRUD app!

Integrating React Bootstrap with React App In the next step, we will install the React Bootstrap front-end framework in our MERN stack app. This framework will allow us to use the Bootstrap’s UI component in our React CRUD app. React Bootstrap allows us to import individual UI components instead of importing the whole set of libraries. npm install react-bootstrap bootstrap Then, go to src/app.js and import the following Bootstrap CSS above App.css file. import 'bootstrap/dist/css/bootstrap.css' ; You can add <link> tag in your React app’s index.html file to use the Bootstrap UI components. You can also import individual Bootstrap 4 components in your React CRUD app.

Creating Simple React Components In this step, we will learn to create react components for managing data in the MERN stack CRUD application. Head over to src folder, make a folder and name it components and within that directory create the following components. create-student.component.js

edit-student.component.js

student-list.component.js Go to src/components/create-student.component.js and add the following code. import React , { Component } from "react" ; export default class CreateStudent extends Component { render ( ) { return ( < div > < p > React Create Student Component! </ p > </ div > ) ; } } Go to src/components/edit-student.component.js and add the following code. import React , { Component } from "react" ; export default class EditStudent extends Component { render ( ) { return ( < div > < p > React Edit Student Component! </ p > </ div > ) ; } } Go to src/components/student-list.component.js and add the following code. import React , { Component } from "react" ; export default class StudentList extends Component { render ( ) { return ( < div > < p > React Student List Component! </ p > </ div > ) ; } }

Implementing React Router In this step, we will implement router in React.js app. Enter the command in terminal and hit enter to install the React Router. npm install react-router-dom --save Next, head over to src/index.js file and tie the App component with the help of <BrowserRouter> object. import React from "react" ; import ReactDOM from "react-dom" ; import { BrowserRouter } from "react-router-dom" ; import "./index.css" ; import App from "./App" ; import * as serviceWorker from "./serviceWorker" ; ReactDOM . render ( < BrowserRouter > < App /> </ BrowserRouter > , document . getElementById ( "root" ) ) ; serviceWorker . unregister ( ) ; Next, include the menu in our React CRUD app. Add the given below code in the src/App.js . import React from "react" ; import Nav from "react-bootstrap/Nav" ; import Navbar from "react-bootstrap/Navbar" ; import Container from "react-bootstrap/Container" ; import Row from "react-bootstrap/Row" ; import Col from "react-bootstrap/Col" ; import "bootstrap/dist/css/bootstrap.css" ; import "./App.css" ; import { BrowserRouter as Router , Switch , Route , Link } from "react-router-dom" ; import CreateStudent from "./components/create-student.component" ; import EditStudent from "./components/edit-student.component" ; import StudentList from "./components/student-list.component" ; function App ( ) { return ( < Router > < div className = " App " > < header className = " App-header " > < Navbar bg = " dark " variant = " dark " > < Container > < Navbar.Brand > < Link to = { "/create-student" } className = " nav-link " > React MERN Stack App </ Link > </ Navbar.Brand > < Nav className = " justify-content-end " > < Nav > < Link to = { "/create-student" } className = " nav-link " > Create Student </ Link > </ Nav > { } < Nav > < Link to = { "/student-list" } className = " nav-link " > Student List </ Link > </ Nav > </ Nav > </ Container > </ Navbar > </ header > < Container > < Row > < Col md = { 12 } > < div className = " wrapper " > < Switch > < Route exact path = ' / ' component = { CreateStudent } /> < Route path = " /create-student " component = { CreateStudent } /> < Route path = " /edit-student/:id " component = { EditStudent } /> < Route path = " /student-list " component = { StudentList } /> </ Switch > </ div > </ Col > </ Row > </ Container > </ div > </ Router > ) ; } export default App ;

Create React Form with React Bootstrap In this step, we will build the form using React Bootstrap front-end framework for submitting the Student data in the create-student.component.js component. import React , { Component } from "react" ; import Form from 'react-bootstrap/Form' import Button from 'react-bootstrap/Button' ; export default class CreateStudent extends Component { render ( ) { return ( < div class = " form-wrapper " > < Form > < Form.Group controlId = " Name " > < Form.Label > Name </ Form.Label > < Form.Control type = " text " /> </ Form.Group > < Form.Group controlId = " Email " > < Form.Label > Email </ Form.Label > < Form.Control type = " email " /> </ Form.Group > < Form.Group controlId = " Name " > < Form.Label > Roll No </ Form.Label > < Form.Control type = " text " /> </ Form.Group > < Button variant = " danger " size = " lg " block = " block " type = " submit " > Create Student </ Button > </ Form > </ div > ) ; } }

Submit Forms Data in React Next, we will learn to submit the Forms data in React.js. We have already created the Student form, and need to submit student’s: Name, Email and Roll No to the database. We will start by creating the constructor inside the CreateStudent component class. Then set the initial state of the CreateStudent component by setting this.state Object. Then declare the various functions with every React form field value, so when the user inserts the data within the form input field, a state will be set accordingly. Next, we need to define the submit event, which will allow us to create new student data when the user clicks on `Create Student` submit button. import React , { Component } from "react" ; import Form from 'react-bootstrap/Form' import Button from 'react-bootstrap/Button' ; export default class CreateStudent extends Component { constructor ( props ) { super ( props ) this . onChangeStudentName = this . onChangeStudentName . bind ( this ) ; this . onChangeStudentEmail = this . onChangeStudentEmail . bind ( this ) ; this . onChangeStudentRollno = this . onChangeStudentRollno . bind ( this ) ; this . onSubmit = this . onSubmit . bind ( this ) ; this . state = { name : '' , email : '' , rollno : '' } } onChangeStudentName ( e ) { this . setState ( { name : e . target . value } ) } onChangeStudentEmail ( e ) { this . setState ( { email : e . target . value } ) } onChangeStudentRollno ( e ) { this . setState ( { rollno : e . target . value } ) } onSubmit ( e ) { e . preventDefault ( ) console . log ( ` Student successfully created! ` ) ; console . log ( ` Name: ${ this . state . name } ` ) ; console . log ( ` Email: ${ this . state . email } ` ) ; console . log ( ` Roll no: ${ this . state . rollno } ` ) ; this . setState ( { name : '' , email : '' , rollno : '' } ) } render ( ) { return ( < div className = " form-wrapper " > < Form onSubmit = { this . onSubmit } > < Form.Group controlId = " Name " > < Form.Label > Name </ Form.Label > < Form.Control type = " text " value = { this . state . name } onChange = { this . onChangeStudentName } /> </ Form.Group > < Form.Group controlId = " Email " > < Form.Label > Email </ Form.Label > < Form.Control type = " email " value = { this . state . email } onChange = { this . onChangeStudentEmail } /> </ Form.Group > < Form.Group controlId = " Name " > < Form.Label > Roll No </ Form.Label > < Form.Control type = " text " value = { this . state . rollno } onChange = { this . onChangeStudentRollno } /> </ Form.Group > < Button variant = " danger " size = " lg " block = " block " type = " submit " > Create Student </ Button > </ Form > </ div > ) ; } }

Build Node JS Backend for MERN Stack We will create a folder inside our React app to manage the `backend` services such as database, models, schema, routes and APIs, name this folder backend. Run command to create backend folder and get inside of it. mkdir backend && cd backend Then, we need to create a separate package.json file for managing the backend of our React CRUD demo app example. npm init Next, install the given below Node dependencies for MERN stack backend. npm install mongoose express cors body-parser NPM Detail Express It’s a robust Node.js web application framework that helps in creating powerful REST APIs. MongoDB It’s a NoSQL document-oriented database for creating a robust web application. CORS It’s a node.js package helps in enabling Access-Control-Allow-Origin CORS header. bodyParser This package extracts the entire body portion of an incoming request stream and exposes it on req.body. Install the nodemon dependency to automate the server restarting process. npm install nodemon --save-dev Your final package.json file will look something like this. { "name" : "mearn-stack-backend" , "version" : "1.0.0" , "description" : "MERN Stack backend" , "main" : "server.js" , "scripts" : { "test" : "echo \"Error: no test specified\" && exit 1" } , "author" : "Digamber Rawat" , "license" : "ISC" , "dependencies" : { "body-parser" : "^1.19.0" , "cors" : "^2.8.5" , "express" : "^4.17.1" , "mongoose" : "^5.6.9" } , "devDependencies" : { "nodemon" : "^1.19.1" } }

Setting up MongoDB Database Next, we will set up a MongoDB database for React MERN stack app. We have already installed mongoDB, create database folder inside the backend folder and create a file by the name of db.js and paste the following code inside of it. module . exports = { db : 'mongodb://localhost:27017/reactdb' } ; We have declared the mongoDB database, here 'reactdb' is the database name. Locally it doesn’t require user name and password; however, in the production, you must create an admin and assign the database to a specific user.

Define Mongoose Schema Then, create a mongoDB schema for interacting with mongoDB database. Create a folder inside backend folder to keep schema related files and name it Models and create a file Student.js inside of it. mkdir Models && cd Models && touch Student.js Next, include the following code in backend/models/Student.js file: const mongoose = require ( 'mongoose' ) ; const Schema = mongoose . Schema ; let studentSchema = new Schema ( { name : { type : String } , email : { type : String } , rollno : { type : Number } } , { collection : 'students' } ) module . exports = mongoose . model ( 'Student' , studentSchema ) We declared a name, email and rollno fields along with their respective data types in student Schema.

Create Routes Using Express/Node JS for React CRUD App In this step, we are building routes (REST APIs) for React CRUD CREATE, READ, UPDATE and DELETE app using Express and Node.js. These routes will help us to manage the data in our React MERN stack student app. Create a folder and name it routes, here we will keep all the routes related files. Also, create the student.routes.js file inside this folder in this file we will define REST APIs. mkdir routes && cd routes && touch student.route.js Then, go to backend/routes/student.route.js file and add the following code. let mongoose = require ( 'mongoose' ) , express = require ( 'express' ) , router = express . Router ( ) ; let studentSchema = require ( '../models/Student' ) ; router . route ( '/create-student' ) . post ( ( req , res , next ) => { studentSchema . create ( req . body , ( error , data ) => { if ( error ) { return next ( error ) } else { console . log ( data ) res . json ( data ) } } ) } ) ; router . route ( '/' ) . get ( ( req , res ) => { studentSchema . find ( ( error , data ) => { if ( error ) { return next ( error ) } else { res . json ( data ) } } ) } ) router . route ( '/edit-student/:id' ) . get ( ( req , res ) => { studentSchema . findById ( req . params . id , ( error , data ) => { if ( error ) { return next ( error ) } else { res . json ( data ) } } ) } ) router . route ( '/update-student/:id' ) . put ( ( req , res , next ) => { studentSchema . findByIdAndUpdate ( req . params . id , { $ set : req . body } , ( error , data ) => { if ( error ) { return next ( error ) ; console . log ( error ) } else { res . json ( data ) console . log ( 'Student updated successfully !' ) } } ) } ) router . route ( '/delete-student/:id' ) . delete ( ( req , res , next ) => { studentSchema . findByIdAndRemove ( req . params . id , ( error , data ) => { if ( error ) { return next ( error ) ; } else { res . status ( 200 ) . json ( { msg : data } ) } } ) } ) module . exports = router ;

Configure Server.js in Node/Express.js Backend We have almost created everything to set up the Node and Expresss.js backend for React 16.9.0 MERN Stack CRUD app. Now we will create the server.js file in the root of the backend folder. Run command from the root of the backend folder to create server.js file. touch server.js Paste the following code inside the backend/server.js file. let express = require ( 'express' ) ; let mongoose = require ( 'mongoose' ) ; let cors = require ( 'cors' ) ; let bodyParser = require ( 'body-parser' ) ; let dbConfig = require ( './database/db' ) ; const studentRoute = require ( '../backend/routes/student.route' ) mongoose . Promise = global . Promise ; mongoose . connect ( dbConfig . db , { useNewUrlParser : true } ) . then ( ( ) => { console . log ( 'Database sucessfully connected!' ) } , error => { console . log ( 'Could not connect to database : ' + error ) } ) const app = express ( ) ; app . use ( bodyParser . json ( ) ) ; app . use ( bodyParser . urlencoded ( { extended : true } ) ) ; app . use ( cors ( ) ) ; app . use ( '/students' , studentRoute ) const port = process . env . PORT || 4000 ; const server = app . listen ( port , ( ) => { console . log ( 'Connected to port ' + port ) } ) app . use ( ( req , res , next ) => { next ( createError ( 404 ) ) ; } ) ; app . use ( function ( err , req , res , next ) { console . error ( err . message ) ; if ( ! err . statusCode ) err . statusCode = 500 ; res . status ( err . statusCode ) . send ( err . message ) ; } ) ; Now, we have created the backend for our MERN stack app. Open the terminal and run the command to start MongoDB, It will allow you to save the student data in the database. mongod Also, open another terminal and run the following command to start the Nodemon server by staying in the backend folder. nodemon server.js Following will be your APIs routes created with Express.js, MongoDB and Node.js. REST API URL GET http://localhost:4000/students POST /students/create-student GET /students/edit-student/id PUT /students/update-student/id DELETE /students/delete-student/id You can also test these APIs in Postmen API development tool, click here to download Postmen.

Using Axios with React to Make HTTP Request In this step, we will learn to use the Axios library in React MERN Stack app to handle the HTTP request. Axios is a promise-based HTTP client for the browser and node.js. It offers the following features. Make XMLHttpRequests from the browser

Handle http requests from node.js

Supports the Promise API

Intercept request and response

Transform request and response data

Cancel requests

Self-regulating for JSON data

Client-side protection from XSRF Run command in the terminal to install axios in React CRUD app. npm install axios Next, we will send the student’s data to the MongoDB server as an object using the Axios post http method. import React , { Component } from "react" ; import Form from 'react-bootstrap/Form' import Button from 'react-bootstrap/Button' ; import axios from 'axios' ; export default class CreateStudent extends Component { constructor ( props ) { super ( props ) this . onChangeStudentName = this . onChangeStudentName . bind ( this ) ; this . onChangeStudentEmail = this . onChangeStudentEmail . bind ( this ) ; this . onChangeStudentRollno = this . onChangeStudentRollno . bind ( this ) ; this . onSubmit = this . onSubmit . bind ( this ) ; this . state = { name : '' , email : '' , rollno : '' } } onChangeStudentName ( e ) { this . setState ( { name : e . target . value } ) } onChangeStudentEmail ( e ) { this . setState ( { email : e . target . value } ) } onChangeStudentRollno ( e ) { this . setState ( { rollno : e . target . value } ) } onSubmit ( e ) { e . preventDefault ( ) const studentObject = { name : this . state . name , email : this . state . email , rollno : this . state . rollno } ; axios . post ( 'http://localhost:4000/students/create-student' , studentObject ) . then ( res => console . log ( res . data ) ) ; this . setState ( { name : '' , email : '' , rollno : '' } ) } render ( ) { return ( < div className = " form-wrapper " > < Form onSubmit = { this . onSubmit } > < Form.Group controlId = " Name " > < Form.Label > Name </ Form.Label > < Form.Control type = " text " value = { this . state . name } onChange = { this . onChangeStudentName } /> </ Form.Group > < Form.Group controlId = " Email " > < Form.Label > Email </ Form.Label > < Form.Control type = " email " value = { this . state . email } onChange = { this . onChangeStudentEmail } /> </ Form.Group > < Form.Group controlId = " Name " > < Form.Label > Roll No </ Form.Label > < Form.Control type = " text " value = { this . state . rollno } onChange = { this . onChangeStudentRollno } /> </ Form.Group > < Button variant = " danger " size = " lg " block = " block " type = " submit " > Create Student </ Button > </ Form > </ div > ) ; } } Then enter the student name, email and rollno and click on Create Student button and your data will be saved in MongoDB NoSQL database.

Show Data List with React Axios In this step, we will show the student’s data list using React Axios and react bootstrap. Add the given below code inside the src/components/student-list.component.js . import React , { Component } from "react" ; import axios from 'axios' ; import Table from 'react-bootstrap/Table' ; import StudentTableRow from './StudentTableRow' ; export default class StudentList extends Component { constructor ( props ) { super ( props ) this . state = { students : [ ] } ; } componentDidMount ( ) { axios . get ( 'http://localhost:4000/students/' ) . then ( res => { this . setState ( { students : res . data } ) ; } ) . catch ( ( error ) => { console . log ( error ) ; } ) } DataTable ( ) { return this . state . students . map ( ( res , i ) => { return < StudentTableRow obj = { res } key = { i } /> ; } ) ; } render ( ) { return ( < div className = " table-wrapper " > < Table striped bordered hover > < thead > < tr > < th > Name </ th > < th > Email </ th > < th > Roll No </ th > < th > Action </ th > </ tr > </ thead > < tbody > { this . DataTable ( ) } </ tbody > </ Table > </ div > ) ; } } In the above code, we are making HTTP GET request using React Axios and Node/Express JS REST API. We are using React-Bootstrap table to show the Students data on the frontend. In the next step, we will create the component and name it StudentTableRow.js and keep it in the components folder. We have already imported the component in the student-list.component.js file. Then add the given below code inside the components/StudentTableRow.js file. import React , { Component } from 'react' ; import { Link } from 'react-router-dom' ; import Button from 'react-bootstrap/Button' ; export default class StudentTableRow extends Component { render ( ) { return ( < tr > < td > { this . props . obj . name } </ td > < td > { this . props . obj . email } </ td > < td > { this . props . obj . rollno } </ td > < td > < Link className = " edit-link " to = { "/edit-student/" + this . props . obj . _id } > Edit </ Link > < Button size = " sm " variant = " danger " > Delete </ Button > </ td > </ tr > ) ; } }

Edit, Update and Delete Data in React In this step, we will create edit and update functionality for the user to manage the student data in React v16.9.0. We used the Axios library and making the PUT request to update the data in MongoDB database using REST API built with Node and Express JS. Include the given below code inside the student-edit.component.js file. import React , { Component } from "react" ; import Form from 'react-bootstrap/Form' import Button from 'react-bootstrap/Button' ; import axios from 'axios' ; export default class EditStudent extends Component { constructor ( props ) { super ( props ) this . onChangeStudentName = this . onChangeStudentName . bind ( this ) ; this . onChangeStudentEmail = this . onChangeStudentEmail . bind ( this ) ; this . onChangeStudentRollno = this . onChangeStudentRollno . bind ( this ) ; this . onSubmit = this . onSubmit . bind ( this ) ; this . state = { name : '' , email : '' , rollno : '' } } componentDidMount ( ) { axios . get ( 'http://localhost:4000/students/edit-student/' + this . props . match . params . id ) . then ( res => { this . setState ( { name : res . data . name , email : res . data . email , rollno : res . data . rollno } ) ; } ) . catch ( ( error ) => { console . log ( error ) ; } ) } onChangeStudentName ( e ) { this . setState ( { name : e . target . value } ) } onChangeStudentEmail ( e ) { this . setState ( { email : e . target . value } ) } onChangeStudentRollno ( e ) { this . setState ( { rollno : e . target . value } ) } onSubmit ( e ) { e . preventDefault ( ) const studentObject = { name : this . state . name , email : this . state . email , rollno : this . state . rollno } ; axios . put ( 'http://localhost:4000/students/update-student/' + this . props . match . params . id , studentObject ) . then ( ( res ) => { console . log ( res . data ) console . log ( 'Student successfully updated' ) } ) . catch ( ( error ) => { console . log ( error ) } ) this . props . history . push ( '/student-list' ) } render ( ) { return ( < div className = " form-wrapper " > < Form onSubmit = { this . onSubmit } > < Form.Group controlId = " Name " > < Form.Label > Name </ Form.Label > < Form.Control type = " text " value = { this . state . name } onChange = { this . onChangeStudentName } /> </ Form.Group > < Form.Group controlId = " Email " > < Form.Label > Email </ Form.Label > < Form.Control type = " email " value = { this . state . email } onChange = { this . onChangeStudentEmail } /> </ Form.Group > < Form.Group controlId = " Name " > < Form.Label > Roll No </ Form.Label > < Form.Control type = " text " value = { this . state . rollno } onChange = { this . onChangeStudentRollno } /> </ Form.Group > < Button variant = " danger " size = " lg " block = " block " type = " submit " > Update Student </ Button > </ Form > </ div > ) ; } } Make Axios Delete Request to Delete Data Lastly, we will be building the delete functionality in our React CRUD demo app. Go to components/StudentTableRow.js file and call the Node/Express API to delete the student data from the MongoDB database. import React , { Component } from 'react' ; import { Link } from 'react-router-dom' ; import axios from 'axios' ; import Button from 'react-bootstrap/Button' ; export default class StudentTableRow extends Component { constructor ( props ) { super ( props ) ; this . deleteStudent = this . deleteStudent . bind ( this ) ; } deleteStudent ( ) { axios . delete ( 'http://localhost:4000/students/delete-student/' + this . props . obj . _id ) . then ( ( res ) => { console . log ( 'Student successfully deleted!' ) } ) . catch ( ( error ) => { console . log ( error ) } ) } render ( ) { return ( < tr > < td > { this . props . obj . name } </ td > < td > { this . props . obj . email } </ td > < td > { this . props . obj . rollno } </ td > < td > < Link className = " edit-link " to = { "/edit-student/" + this . props . obj . _id } > Edit </ Link > < Button onClick = { this . deleteStudent } size = " sm " variant = " danger " > Delete </ Button > </ td > </ tr > ) ; } }