JSMERN stackHow to create a MERN stack app in 4 Steps? Section 1

How to create a MERN stack app in 4 Steps? Section 1

In this series of MERN stack tutorial we are going to learn frontend as well as backend

  • Section 1: Setting Up the Project
  • Section 2: Setting up the backend
  • Section 3: Connection of Back-end to Front-end
  • Section 4: Finish the application

In this tutorial series, we will investigate the MERN stack by developing a real-world application from start to finish. The MERN stack consists of the following technology:

  • NodeJs : Node.js is a JavaScript runtime based on the Chrome V8 JavaScript engine. Node.js would add JavaScript to the server.
  • MongoDB : A document-based open source database.
  • Express : Quick, unrecognized, minimalist web framework for Node.js.
  • ReactJS : A JavaScript front-end library for building user interfaces.

The MERN stack is very similar to that of the popular MEAN stack. The only distinction here is that the MEAN stack uses Angular to construct a front-end web server, and the MERN stack uses React instead.

The program we’re going to create in this tutorial series is a basic to-do application. Using this example, you will see how to construct a CRUD (Create, Read, Edit , and Delete) application from scratch using the MERN stack!

In this first part of this section, we will complete the setup of the React project to create the front-end part of the MERN stack sample program. In the next section, we’re going to continue integrating the Node.js/Express server.

Setting Up The React Application for MERN Stack application

This tutorial assumes that Node.js is installed on your machine. If this is not the case, please go to https:/nodejs.org/ first and follow the installation instructions for your framework.

You will verify whether Node.js is built on your device by entering:

$ node -v

On the cmd prompt or terminal. This will print the version of Node.js that is installed on your machine.

MERN stack nodejs version check

Executing this command opens a new todo-mean-stack-app project directory. Inside this folder, you can find the default React project template with all the dependencies enabled. Shift to the newly created folder:

cd .\todo-mean-stack-app

And launch the web server by running the following command:

npm start

You should now be able to see the following result in the browser:

React app setup for MERN Stack

Now add some spices(Bootstrap) into our React frontend of the MERN stack app

First, we need to add our project to the Bootstrap framework. This is required because we’re going to use the Bootstrap CSS classes to create our user interface. Invoke the following command to add the library within the project folder:

import 'bootstrap/dist/css/bootstrap.min.css';

In addition, you need to delete much of the default code found in App.js, so that only the following code remains:

import logo from './logo.svg';
import './App.css';
import 'bootstrap/dist/css/bootstrap.min.css';

function App() {
  return (
    <div className="container">
    <h2>Todo MERN-Stack App</h2>
  </div>
  );
}

export default App;

How to setup Up React Router in todo MERN stack app

The next thing we need to apply to the project is the React Router package: react-router-dom:

npm install react-router-dom

We’re ready to add the routing setup to App.js with this package installed. First of all, the following import statement must be added:

import { BrowserRouter as Router, Route, Link } from 'react-router-dom';

Next, let’s add the JSX code to the < Router></Router > element:

import logo from './logo.svg';
import './App.css';
import 'bootstrap/dist/css/bootstrap.min.css';
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';

function App() {
  return (
    <Router>
        <div className="container">
          <h2>MERN-Stack Todo App</h2>
        </div>
      </Router>
  );
}

export default App;

Within the < Router > element, we are now able to add the configuration of the router inside that element:

<Route path="/" exact component={TodosList} />
<Route path="/modify/:id" component={ModifyTodo} />
<Route path="/make" component={MakeTodo} />

A new < Route > feature is added for each route that needs to be added to the application. The path and component attributes are used to add configuration settings for each route. By using the path parameter, the routing path is set and the path is connected to the component by using the attribute component.

As you will see, we need to connect three routes to our components:

RouteComponents
/TodosList
/modifyModifyTodo
/makeMakeTodo

So lets create components of our MERN stack app

To build the necessary components in our program, first create a new src/components directory and create three new files:

todos-list.component.js

import React, { Component } from 'react';

export default class TodosList extends Component {
    render() {
        return (
            <div>
                <p>Welcome to Todos List Component!!</p>
            </div>
        )
    }
}

modify-list.component.js

import React, { Component } from 'react';

export default class ModifyTodo extends Component {
    render() {
        return (
            <div>
                <p>Welcome to Modify Todo Component!!</p>
            </div>
        )
    }
}

bulid-todo.component.js

import React, { Component } from 'react';

export default class BulidTodo extends Component {
    render() {
        return (
            <div>
                <p>Welcome to BulidTodo Todo Component!!</p>
            </div>
        )
    }
}

Lets create The Basic Layout & Navigation of MERN stack app

Next, add a simple interface and navigation menu to our submission. Since we added the bootstrap library before we could use the bootstrap CSS classes to enforce the user interface of our web application. Extend the code to the following in App.js:

import React, { Component } from 'react';
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';
import "bootstrap/dist/css/bootstrap.min.css";

import BulidTodo from "./components/bulid-todo.component";
import ModifyTodo from "./components/modify-todo.component";
import TodosList from "./components/todos-list.component";

import logo from "./Logo-onUrDesk.jpg";

class App extends Component {
  render() {
    return (
      <Router>
        <div className="container">
          
          <nav className="navbar navbar-expand-lg navbar-light bg-light">
            <a className="navbar-brand" href="https://onurdesk.com">
              <img src={logo} width="30" height="30" alt="onurdesk.com" />
            </a>
            <Link to="/" className="navbar-brand">MERN-Stack Todo App</Link>
            <div className="collpase nav-collapse">
              <ul className="navbar-nav mr-auto">
                <li className="navbar-item">
                  <Link to="/" className="nav-link">Todos</Link>
                </li>
                <li className="navbar-item">
                  <Link to="/create" className="nav-link">Create Todo</Link>
                </li>
              </ul>
            </div>
          </nav>

          <Route path="/" exact component={TodosList} />
          <Route path="/modify/:id" component={ModifyTodo} />
          <Route path="/bulid" component={BulidTodo} />
        </div>
      </Router>
    );
  }
}

export default App;

Let have alook at browser

Let’s start implementing components for BulidTodo Components of the MERN stack app

In the next stage, apply the BuildTodo component implementation to the bulid-todo.component.js file. First, we begin by adding a builder to the class of components:

 constructor(props) {
        super(props);

        this.state = {
            todo_description: '',
            todo_responsible: '',
            todo_priority: '',
            todo_completed: false
        }
    }

Inside the constructor, we set the initial state of the component by assigning an object to this.state. The state shall contain the following properties:

  • todo_description: ”,
  • todo_responsible: ”,
  • todo_priority: ”,
  • todo_completed: false

In addition, we need to add methods that can be used to change state properties:

onChangeTodoDescription(e) {
        this.setState({
            todo_description: e.target.value
        });
    }

    onChangeTodoResponsible(e) {
        this.setState({
            todo_responsible: e.target.value
        });
    }

    onChangeTodoPriority(e) {
        this.setState({
            todo_priority: e.target.value
        });
    }

At the end , a particular approach is required to handle the submitted event of the type that will be applied to build a new todo item:

onSubmit(e) {
        e.preventDefault();
        
        console.log(`Form submitted:`);
        console.log(`Todo Description: ${this.state.todo_description}`);
        console.log(`Todo Responsible: ${this.state.todo_responsible}`);
        console.log(`Todo Priority: ${this.state.todo_priority}`);
        
        this.setState({
            todo_description: '',
            todo_responsible: '',
            todo_priority: '',
            todo_completed: false
        })
    }

Within this method, we need to call e.preventDefault to ensure that the default HTML form submission behavior is prevented. Since the back-end of our program has not been introduced yet we are just printing out what is actually available in the local part state of the console. Finally , we make sure that the form is reset by setting the state entity to be reset.

Since we’re dealing with the state object of the part in the four methods implemented, we need to make sure that we connect certain methods to it by adding the following lines of code to the constructor:

   this.onChangeTodoDescription = this.onChangeTodoDescription.bind(this);
        this.onChangeTodoResponsible = this.onChangeTodoResponsible.bind(this);
        this.onChangeTodoPriority = this.onChangeTodoPriority.bind(this);
        this.onSubmit = this.onSubmit.bind(this);

Finally, we need to add the JSX code needed to show the form:

render() {
        return (
            <div style={{marginTop: 10}}>
                <h3>Create New Todo</h3>
                <form onSubmit={this.onSubmit}>
                    <div className="form-group"> 
                        <label>Description: </label>
                        <input  type="text"
                                className="form-control"
                                value={this.state.todo_description}
                                onChange={this.onChangeTodoDescription}
                                />
                    </div>
                    <div className="form-group">
                        <label>Responsible: </label>
                        <input 
                                type="text" 
                                className="form-control"
                                value={this.state.todo_responsible}
                                onChange={this.onChangeTodoResponsible}
                                />
                    </div>
                    <div className="form-group">
                        <div className="form-check form-check-inline">
                            <input  className="form-check-input" 
                                    type="radio" 
                                    name="priorityOptions" 
                                    id="priorityLow" 
                                    value="Low"
                                    checked={this.state.todo_priority==='Low'} 
                                    onChange={this.onChangeTodoPriority}
                                    />
                            <label className="form-check-label">Low</label>
                        </div>
                        <div className="form-check form-check-inline">
                            <input  className="form-check-input" 
                                    type="radio" 
                                    name="priorityOptions" 
                                    id="priorityMedium" 
                                    value="Medium" 
                                    checked={this.state.todo_priority==='Medium'} 
                                    onChange={this.onChangeTodoPriority}
                                    />
                            <label className="form-check-label">Medium</label>
                        </div>
                        <div className="form-check form-check-inline">
                            <input  className="form-check-input" 
                                    type="radio" 
                                    name="priorityOptions" 
                                    id="priorityHigh" 
                                    value="High" 
                                    checked={this.state.todo_priority==='High'} 
                                    onChange={this.onChangeTodoPriority}
                                    />
                            <label className="form-check-label">High</label>
                        </div>
                    </div>

                    <div className="form-group">
                        <input type="submit" value="Create Todo" className="btn btn-primary" />
                    </div>
                </form>
            </div>
        )
    }

In the following, you can see the entire source code that should now be available in bulid-todo.component.js:

import React, { Component } from 'react';

export default class BulidTodo extends Component {
    
    constructor(props) {
        super(props);

        this.onChangeTodoDescription = this.onChangeTodoDescription.bind(this);
        this.onChangeTodoResponsible = this.onChangeTodoResponsible.bind(this);
        this.onChangeTodoPriority = this.onChangeTodoPriority.bind(this);
        this.onSubmit = this.onSubmit.bind(this);

        this.state = {
            todo_description: '',
            todo_responsible: '',
            todo_priority: '',
            todo_completed: false
        }
    }

    onChangeTodoDescription(e) {
        this.setState({
            todo_description: e.target.value
        });
    }

    onChangeTodoResponsible(e) {
        this.setState({
            todo_responsible: e.target.value
        });
    }

    onChangeTodoPriority(e) {
        this.setState({
            todo_priority: e.target.value
        });
    }

    onSubmit(e) {
        e.preventDefault();
        
        console.log(`Form submitted:`);
        console.log(`Todo Description: ${this.state.todo_description}`);
        console.log(`Todo Responsible: ${this.state.todo_responsible}`);
        console.log(`Todo Priority: ${this.state.todo_priority}`);
        
        this.setState({
            todo_description: '',
            todo_responsible: '',
            todo_priority: '',
            todo_completed: false
        })
    }

    render() {
        return (
            <div style={{marginTop: 10}}>
                <h3>Bulid a New Todo</h3>
                <form onSubmit={this.onSubmit}>
                    <div className="form-group"> 
                        <label>Description: </label>
                        <input  type="text"
                                className="form-control"
                                value={this.state.todo_description}
                                onChange={this.onChangeTodoDescription}
                                />
                    </div>
                    <div className="form-group">
                        <label>Responsible: </label>
                        <input 
                                type="text" 
                                className="form-control"
                                value={this.state.todo_responsible}
                                onChange={this.onChangeTodoResponsible}
                                />
                    </div>
                    <div className="form-group">
                        <div className="form-check form-check-inline">
                            <input  className="form-check-input" 
                                    type="radio" 
                                    name="priorityOptions" 
                                    id="priorityLow" 
                                    value="Low"
                                    checked={this.state.todo_priority==='Low'} 
                                    onChange={this.onChangeTodoPriority}
                                    />
                            <label className="form-check-label">Low</label>
                        </div>
                        <div className="form-check form-check-inline">
                            <input  className="form-check-input" 
                                    type="radio" 
                                    name="priorityOptions" 
                                    id="priorityMedium" 
                                    value="Medium" 
                                    checked={this.state.todo_priority==='Medium'} 
                                    onChange={this.onChangeTodoPriority}
                                    />
                            <label className="form-check-label">Medium</label>
                        </div>
                        <div className="form-check form-check-inline">
                            <input  className="form-check-input" 
                                    type="radio" 
                                    name="priorityOptions" 
                                    id="priorityHigh" 
                                    value="High" 
                                    checked={this.state.todo_priority==='High'} 
                                    onChange={this.onChangeTodoPriority}
                                    />
                            <label className="form-check-label">High</label>
                        </div>
                    </div>

                    <div className="form-group">
                        <input type="submit" value="Create Todo" className="btn btn-primary" />
                    </div>
                </form>
            </div>
        )
    }


}

The result that is provided to the browser when entering the / build route should fit what you can see in the following:

MERN stack app for build route

Fill the form and submit it by pressing the Build Todo button would output the data entered in the console:

What Next for MERN stack app ?

In this first part of this sequence, we began to set up a React-based front-end project and completed the first phase of implementation.
In the next section, we will begin building the MERN stack all sample framework by setting up the backend using Node.js, Express and MongoDB.

Get Social for Us :-

1 COMMENT

LEAVE A REPLY

Please enter your comment!
Please enter your name here

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Subscribe Today

GET EXCLUSIVE FULL ACCESS TO PREMIUM CONTENT

Get unlimited access to our EXCLUSIVE Content and our archive of subscriber stories.

Exclusive content

Latest article

More article