How to Set up a Node.js Express Server for React

Here is the step-by-step guide for creating an application that uses React, Node.js, and express server.

Step 1: Install React using create react app.

npx create-react-app react-express-tutorial

After installing, go into that directory.

cd react-express-tutorial

Start the development server.

yarn start

Step 2: Define the routing of components.

Type the following command in your terminal to install the react-router-dom module.

yarn add react-router-dom

It will install the dependency. If you get an error, please install the package manager Yarn. Now, open the code in your favorite editor. I am using Visual Studio Code.

Go to the index.js file and Wrap the BrowserRouter object around the App.js component.

// index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { BrowserRouter } from 'react-router-dom';
import registerServiceWorker from './registerServiceWorker';

ReactDOM.render(
    <BrowserRouter>
        <App />
    </BrowserRouter>, document.getElementById('root'));
registerServiceWorker();

Create one directory called components inside the src folder, and inside that folder, make three components.

  1. CreateComponent.js
  2. EditComponent.js
  3. IndexComponent.js
// CreateComponent.js

import React, { Component } from 'react';

export default class CreateComponent extends Component {
    render() {
        return (
            <div>
                <p>Welcome to Create Component!!</p>
            </div>
        )
    }
}
// EditComponent.js

import React, { Component } from 'react';

export default class EditComponent extends Component {
    render() {
        return (
            <div>
                <p>Welcome to Edit Component!!</p>
            </div>
        )
    }
}
// IndexComponent.js

import React, { Component } from 'react';

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

Now, define the routes for each component.

// App.js

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

import CreateComponent from './components/CreateComponent';
import EditComponent from './components/EditComponent';
import IndexComponent from './components/IndexComponent';

class App extends Component {
  render() {
    return (
    <Router>
        <div>
          <h2>Welcome to React Express Tutorial</h2>
          <ul>
          <li><Link to={'/'}>Home</Link></li>
            <li><Link to={'/create'}>Create</Link></li>
            <li><Link to={'/index'}>List</Link></li>
            <li><Link to={'/edit/:id'}>Edit</Link></li>
          </ul>
          <hr />
          <Switch>
              <Route exact path='/create' component={CreateComponent} />
              <Route path='/edit/:id' component={EditComponent} />
              <Route path='/index' component={IndexComponent} />
          </Switch>
        </div>
      </Router>
    );
  }
}

export default App;

Finally, save the file and go to the http://localhost:3000/

Step 3: Include Bootstrap 4 and create a form.

Install Bootstrap 4 using the following command.

yarn add bootstrap@4.0.0

Afterward, go to the index.js file and import the bootstrap as an NPM dependency.

// index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { BrowserRouter } from 'react-router-dom';
import registerServiceWorker from './registerServiceWorker';

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

ReactDOM.render(
    <BrowserRouter>
        <App />
    </BrowserRouter>, document.getElementById('root'));
registerServiceWorker();

If your development server is running, you can see the bootstrap styles applied to the React Express Application. But, first, give the style to navigation. For that, our code looks like below.

// App.js

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

import CreateComponent from './components/CreateComponent';
import EditComponent from './components/EditComponent';
import IndexComponent from './components/IndexComponent';

class App extends Component {
  render() {
    return (
    <Router>
        <div className="container">
        <nav className="navbar navbar-expand-lg navbar-light bg-light">
            <a className="navbar-brand">React Express App</a>
            <div className="collapse navbar-collapse" id="navbarSupportedContent">
              <ul className="navbar-nav mr-auto">
              <li className="nav-item">
                  <Link to={'/'} className="nav-link">Home</Link>
                </li>
                <li className="nav-item">
                  <Link to={'/create'} className="nav-link">Create</Link>
                </li>
                <li className="nav-item">
                  <Link to={'/index'} className="nav-link">Index</Link>
                </li>
                <li className="nav-item">
                  <Link to={'/edit/:id'} className="nav-link">Edit</Link>
                </li>
              </ul>
            </div>
          </nav>
          <Switch>
              <Route exact path='/create' component={CreateComponent} />
              <Route path='/edit/:id' component={EditComponent} />
              <Route path='/index' component={IndexComponent} />
          </Switch>
        </div>
      </Router>
    );
  }
}

export default App;

Apply marignTop: 50 property to all three components.

// CreateComponent.js

import React, { Component } from 'react';

export default class CreateComponent extends Component {
    render() {
        return (
            <div style={{marginTop: 50}}>
                <p>Welcome to Create Component!!</p>
            </div>
        )
    }
}

Now you can see our design is completely changed.

React Express MongoDB Tutorial

Create a Bootstrap Form

Write the code to generate the bootstrap form inside the CreateComponent.js file.

// CreateComponent.js

import React, { Component } from 'react';

export default class CreateComponent extends Component {
    render() {
        return (
            <div style={{marginTop: 50}}>
                <h3>Add New Server</h3>
                <form>
                    <div className="form-group">
                        <label>Add Host Name:  </label>
                        <input type="text" className="form-control"/>
                    </div>
                    <div className="form-group">
                        <label>Add Server Port: </label>
                        <input type="text" className="form-control"/>
                    </div>
                    <div className="form-group">
                        <input type="submit" value="Add Node server" className="btn btn-primary"/>
                    </div>
                </form>
            </div>
        )
    }
}

create node server

Step 4: Submit the Form.

Okay, now we have two fields.

  1. server name
  2. server port

So we need to create three functions that can track both the values and set the state according to it. Also, the third function will send the POST request to the node express server.

// CreateComponent.js

import React, { Component } from 'react';

export default class CreateComponent extends Component {

    constructor(props) {
        super(props);
        this.onChangeHostName = this.onChangeHostName.bind(this);
        this.onChangePort = this.onChangePort.bind(this);
        this.onSubmit = this.onSubmit.bind(this);

        this.state = {
            name: '',
            port: ''
        }
    }
    onChangeHostName(e) {
        this.setState({
            name: e.target.value
        });
    }
    onChangePort(e) {
        this.setState({
            port: e.target.value
        });
    }
    onSubmit(e) {
        e.preventDefault();
        console.log(`name is ${this.state.name} and port is ${this.state.port}`);
        this.setState({
            name: '',
            port: ''
        })
    }

    render() {
        return (
            <div style={{marginTop: 50}}>
                <h3>Add New Server</h3>
                <form onSubmit={this.onSubmit}>
                    <div className="form-group">
                        <label>Add Host Name:  </label>
                        <input type="text" value={this.state.name} className="form-control" onChange={this.onChangeHostName}/>
                    </div>
                    <div className="form-group">
                        <label>Add Server Port: </label>
                        <input type="text" value={this.state.port} className="form-control" onChange={this.onChangePort}/>
                    </div>
                    <div className="form-group">
                        <input type="submit" value="Add Node server" className="btn btn-primary"/>
                    </div>
                </form>
            </div>
        )
    }
}

So, when you submit the form, you can see that we can get both textbox values in the console. So, those values will be sent to the Node.js server and saved into the database.

Step 5: Create a Node.js server and install Express Framework.

Take a break from the front-end part and go to the back-end part of our application. First, inside our project root, create one folder called server. Then, inside the server folder, create one file called server.js. Now, install the express as well as other dependencies.

yarn add express nodemon body-parser cors mongoose
// server.js

const express = require('express');
const app = express();
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const PORT = 4200;
const cors = require('cors');

app.use(cors());
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());

app.listen(PORT, function(){
  console.log('Server is running on Port: ',PORT);
});

I have imported all the required packages inside a server.js file.

Okay, now start the Node.js server using the following command.

nodemon server/server

The first server is the folder name, and the second is a server.js file.

You can see in the terminal that the Node js server is running at PORT: 4200.

Step 6: Set up the MongoDB database.

I have already installed MongoDB on Mac. So I am starting the MongoDB server by the following command.

mongod

Also, I need to start the Mongo Shell to interact with the database. So in another tab of the terminal, type the following command to open Mongo Shell.

mongo

Step 7: Connect Express App to Mongo Database.

Inside the server folder, create one folder called the database. Inside the database folder, create one file called DB.js.

// DB.js

module.exports = {
    DB: 'mongodb://localhost:27017/reactexpress'
}

My username and password are empty in my local database, but in the production, you need to create one admin user and assign the database to that user.

Now, import this DB.js file into the server.js file.

// server.js

const express = require('express');
const app = express();
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const PORT = 4200;
const cors = require('cors');
const config = require('./database/DB');

mongoose.connect(config.DB).then(
    () => {console.log('Database is connected') },
    err => { console.log('Can not connect to the database' +err)
});

app.use(cors());
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());

app.listen(PORT, function(){
  console.log('Server is running on Port: ',PORT);
});

Save the file, and see the terminal; you can see that our database is connected with our Express application.

Step 8: Create a Mongoose schema.

Create one folder inside the server folder called models. Then, inside the model’s foldercreate one file called ServerPort.js.

// ServerPort.js

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

// Define collection and schema for Items
var ServerPort = new Schema({
  name: {
    type: String
  },
  port: {
      type: Number
  }
},{
    collection: 'servers'
});

module.exports = mongoose.model('ServerPort', ServerPort);

Step 9: Create Express routes for the application.

Inside the server folder, create one folder called routes. Then, inside that routes folder, create one file called ServerPortRouter.js.

// ServerPortRouter.js

const express = require('express');
const app = express();
const ServerPortRouter = express.Router();

const ServerPort = require('../models/ServerPort');

ServerPortRouter.route('/add').post(function (req, res) {
  const serverport = new ServerPort(req.body);
  serverport.save()
    .then(serverport => {
        res.json('Server added successfully');
    })
    .catch(err => {
    res.status(400).send("unable to save to database");
    });
});

ServerPortRouter.route('/').get(function (req, res) {
    ServerPort.find(function (err, serverports){
    if(err){
      console.log(err);
    }
    else {
      res.json(serverports);
    }
  });
});

ServerPortRouter.route('/edit/:id').get(function (req, res) {
  const id = req.params.id;
  ServerPort.findById(id, function (err, serverport){
      res.json(serverport);
  });
});

ServerPortRouter.route('/update/:id').post(function (req, res) {
    ServerPort.findById(req.params.id, function(err, serverport) {
    if (!serverport)
      return next(new Error('Could not load Document'));
    else {
      // do your updates here
      serverport.name = req.body.name;
      serverport.port = req.body.port;

      serverport.save().then(serverport => {
          res.json('Update complete');
      })
      .catch(err => {
            res.status(400).send("unable to update the database");
      });
    }
  });
});

ServerPortRouter.route('/delete/:id').get(function (req, res) {
    ServerPort.findByIdAndRemove({_id: req.params.id},
       function(err, serverport){
        if(err) res.json(err);
        else res.json('Successfully removed');
    });
});

module.exports = ServerPortRouter;

The last step is to import this ServerPortRouter.js file into the server.js file. So the final server.js file looks like below.

// server.js

const express = require('express');
const app = express();
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const PORT = 4200;
const cors = require('cors');

const config = require('./database/DB');
const ServerPortRouter = require('./routes/ServerPortRoutes');

mongoose.connect(config.DB).then(
    () => {console.log('Database is connected') },
    err => { console.log('Can not connect to the database' +err)
});

app.use(cors());
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());

app.use('/serverport', ServerPortRouter);

app.listen(PORT, function(){
  console.log('Server is running on Port: ',PORT);
});

Step 10: Install the Axios library and send the POST request to the server.

We use the Axios library for the network request to the Node.js server. So let’s install it first.

yarn add axios

Send the post request and form data to the node js server.

// CreateComponent.js

onSubmit(e) {
        e.preventDefault();
        const serverport = {
            name: this.state.name,
            port: this.state.port
        }
        axios.post('http://localhost:4200/serverport/add', serverport)
        .then(res => console.log(res.data));
        this.setState({
            name: '',
            port: ''
        })
    }

Now, fill in the values and submit the form. Then, open your console panel and see the response.

Success Response

Also, now check the database and see the values.

React Node js tutorial

So, our data is added successfully.

Step 11: Display the server data.

Write the following code inside the IndexComponent.js file.

// IndexComponent.js

import React, { Component } from 'react';
import axios from 'axios';
import TableRow from './TableRow';

export default class IndexComponent extends Component {

  constructor(props) {
      super(props);
      this.state = {serverports: []};
    }
    componentDidMount(){
      axios.get('http://localhost:4200/serverport')
      .then(response => {
        this.setState({ serverports: response.data });
      })
      .catch(function (error) {
        console.log(error);
      })
    }
    tabRow(){
        return this.state.serverports.map(function(object, i){
            return <TableRow obj={object} key={i} />;
        });
    }

    render() {
      return (
        <div className="container">
            <table className="table table-striped">
              <thead>
                <tr>
                  <td>ID</td>
                  <td>Name</td>
                  <td>Port</td>
                </tr>
              </thead>
              <tbody>
                {this.tabRow()}
              </tbody>
            </table>
        </div>
      );
    }
  }

Write the stateless TableRow.js component, which we must create inside the components folder.

// TableRow.js

import React, { Component } from 'react';

class TableRow extends Component {
  render() {
    return (
        <tr>
          <td>
            {this.props.obj._id}
          </td>
          <td>
            {this.props.obj.name}
          </td>
          <td>
            {this.props.obj.port}
          </td>
          <td>
            <button className="btn btn-primary">Edit</button>
          </td>
          <td>
            <button className="btn btn-danger">Delete</button>
          </td>
        </tr>
    );
  }
}

export default TableRow;

Step 12: Edit and update the data.

First, add the Link to the TableRow.js file.

// TableRow.js
import { Link } from 'react-router-dom';

<Link to={"/edit/"+this.props.obj._id} className="btn btn-primary">Edit</Link>

Add the following code to the EditComponent.js file.

// EditComponent.js

import React, { Component } from 'react';
import axios from 'axios';

export default class EditComponent extends Component {

    constructor(props) {
        super(props);
        this.onChangeHostName = this.onChangeHostName.bind(this);
        this.onChangePort = this.onChangePort.bind(this);
        this.onSubmit = this.onSubmit.bind(this);

        this.state = {name: '', port: ''};
    }

    componentDidMount() {
        axios.get('http://localhost:4200/serverport/edit/'+this.props.match.params.id)
            .then(response => {
                this.setState({ name: response.data.name, port: response.data.port });
            })
            .catch(function (error) {
                console.log(error);
            })
        }

    onChangeHostName(e) {
        this.setState({
            name: e.target.value
        });
    }
    onChangePort(e) {
        this.setState({
            port: e.target.value
        });
    }
    onSubmit(e) {
        e.preventDefault();
        const serverport = {
            name: this.state.name,
            port: this.state.port
        }
        axios.post('http://localhost:4200/serverport/update/'+this.props.match.params.id, serverport)
        .then(res => console.log(res.data));
        this.setState({
            name: '',
            port: ''
        })
        this.props.history.push('/index');
    }

    render() {
        return (
            <div style={{marginTop: 50}}>
                <h3>Edit New Server</h3>
                <form onSubmit={this.onSubmit}>
                    <div className="form-group">
                        <label>Add Host Name:  </label>
                        <input type="text" value={this.state.name} className="form-control" onChange={this.onChangeHostName}/>
                    </div>
                    <div className="form-group">
                        <label>Add Server Port: </label>
                        <input type="text" value={this.state.port} className="form-control" onChange={this.onChangePort}/>
                    </div>
                    <div className="form-group">
                        <input type="submit" value="Update server" className="btn btn-primary"/>
                    </div>
                </form>
            </div>
        )
    }
}

Here, you can see that our data is updated successfully. Now, the only thing remaining is deleting. So, to create a delete function inside the TableRow.js file.

// TableRow.js

import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import axios from 'axios';

class TableRow extends Component {
    constructor(props) {
        super(props);
        this.delete = this.delete.bind(this);
    }
    delete() {
        axios.get('http://localhost:4200/serverport/delete/'+this.props.obj._id)
            .then(console.log('Deleted'))
            .catch(err => console.log(err))
    }
  render() {
    return (
        <tr>
          <td>
            {this.props.obj._id}
          </td>
          <td>
            {this.props.obj.name}
          </td>
          <td>
            {this.props.obj.port}
          </td>
          <td>
          <Link to={"/edit/"+this.props.obj._id} className="btn btn-primary">Edit</Link>
          </td>
          <td>
            <button onClick={this.delete} className="btn btn-danger">Delete</button>
          </td>
        </tr>
    );
  }
}

export default TableRow;

React CRUD Functionality

That’s it for this tutorial.

Fork Me On Github

9 thoughts on “How to Set up a Node.js Express Server for React”

  1. ./src/App.js
    Module not found: Can’t resolve ‘./components/CreateComponent’ in ‘C:\Users\GCUF\my\src’

    i found this error

    Reply
  2. Hi Krunal, this is a really usefull tutorial, thank you for that.
    The only thing that I don’t understand is why when udating a data, I have to refresh my Index to see the new data. How can I change the props without reloading the page ?

    Reply
  3. Hi Krunal, this is very helpful tutorial.
    Please give answer for the question which is asked by Ynohtna as I am also facing the same issue.
    Hope for your positive response.

    Reply
  4. Hi Krunal, this is a really helpful tutorial.
    Please give response for the question which Ynohtna had asked as I am also facing the same issue.This is also happening while deleting a record.

    Reply
  5. Hello Thank you a lot for this tutorial, I have a problem when I click on submit button , I get this error in console :
    POST http://localhost:4200/serverport/add 404 (Not Found)
    createError.js:17 Uncaught (in promise) Error: Request failed with status code 404
    at createError (createError.js:17)
    at settle (settle.js:19)
    at XMLHttpRequest.handleLoad (xhr.js:78)
    createError @ createError.js:17
    settle @ settle.js:19
    handleLoad @ xhr.js:78
    Promise.then (async)
    onSubmit @ CreateComponent.js:33
    callCallback @ react-dom.development.js:147
    invokeGuardedCallbackDev @ react-dom.development.js:196
    invokeGuardedCallback @ react-dom.development.js:250
    invokeGuardedCallbackAndCatchFirstError @ react-dom.development.js:265
    executeDispatch @ react-dom.development.js:571
    executeDispatchesInOrder @ react-dom.development.js:596
    executeDispatchesAndRelease @ react-dom.development.js:695
    executeDispatchesAndReleaseTopLevel @ react-dom.development.js:704
    forEachAccumulated @ react-dom.development.js:676
    runEventsInBatch @ react-dom.development.js:844
    runExtractedEventsInBatch @ react-dom.development.js:852
    handleTopLevel @ react-dom.development.js:5025
    batchedUpdates$1 @ react-dom.development.js:19916
    batchedUpdates @ react-dom.development.js:2246
    dispatchEvent @ react-dom.development.js:5105
    interactiveUpdates$1 @ react-dom.development.js:19978
    interactiveUpdates @ react-dom.development.js:2267
    dispatchInteractiveEvent @ react-dom.development.js:5081

    I have the same like you normally.
    Thank you a lot for your answer and help.

    PS: I have a question : axios is the only way to get form data with react and node?

    Reply
  6. This tutorial was awesome! I was finally able to sign up a user and save the data in mongo.

    How do I login in a user using Axios and not Passport? Can you please write a tutorial for that? Keep up the good work!

    Reply

Leave a Comment

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