MERN to Kubernetes — Part 2

Jake Peterson
4 min readFeb 22, 2021

--

MERN App React Frontend Setup

In part 1 of this series I setup the MongoDB and Express Backend for this project. In part 2 I will setup the React frontend for the application.

Generate React App Boilerplate

In your IDE open an integrated terminal in the root of the project directory and type the following command:

$ npx create-react-app frontend

This command will create a new folder in the root of the project called frontend with the files needed for the react app boilerplate

Right click the frontend folder that was created and select ‘Open in Integrated Terminal’ to get a separate terminal window for the react frontend

In the terminal windows for the React frontend type the command:

$ npm install

In the frontend folder find the file called package.json and open it

Before the final closing bracket add a new line space and add the following line of code:

"proxy": "http://localhost:4000"

Add a comma after the closing bracket above the line you just added.

Install and setup Node dependencies for the frontend

In the terminal window for the react frontend type the command:

$ npm install axios bootstrap react-router-dom

Run npm install again to ensure everything is installed correctly

$ npm install

Go to the index.js file located in the frontend → src folder and add the following line of code above all the other code on the page on line 1:

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

Setup React Router

In the index.js find the last line that starts with import and add the below line after it:

import { BrowserRouter } from 'react-router-dom';

Find the section in index.js like:

<React.StrictMode><App /></React.StrictMode>,

Modify it to be like:

<BrowserRouter><App /></BrowserRouter>,

Find the App.js file located in the frontend → src folder and open it

Find the line that reads

import './App.css';

Add this below the above line:

import { Switch, Route } from 'react-router-dom';

Create the React Components

In the frontend → src folder create a new folder called components

In the components folder create the following files:

GroceryList.js

AddGrocery.js

GroceryItem.js

Open the newly created AddGrocery.js file and add the following code

import React, { useState } from 'react';import axios from 'axios';function AddGrocery(props) {const groceryService = axios.create({baseURL: '/api'});const initialGroceryState = {name: '',quantity: '',bought: false,}const [grocery, setGrocery] = useState(initialGroceryState);const [successMessage, setSuccessMessage] = useState({ message: '' });const handleSubmit = async (e) => {e.preventDefault();await groceryService.post(`/groceries/new`, grocery);setSuccessMessage({ message: 'Added ' + grocery.name });setGrocery(initialGroceryState);props.handleUpdate();}const handleInputChange = (e) => {const { name, value } = e.target;setGrocery({ ...grocery, [name]: value });};return (<><div className="container"><div className="card"><div className="card-header"><h3>Add Grocery</h3></div><div className="card-body"><form onSubmit={handleSubmit}><div className="form-group"><label>Grocery Name</label><input className="form-control" id="groceryName" name="name" value={grocery.name} onChange={handleInputChange} /></div><div className="form-group"><label>Quantity</label><input className="form-control" id="quantity" name="quantity" value={grocery.quantity} onChange={handleInputChange} /></div><button type="submit" className="btn btn-primary mb-2">Submit</button></form>{successMessage.message}</div></div></div></>);}export default AddGrocery;

Open GroceryItem.js file and add the following code:

import React from 'react'function GroceryItem(props) {const sendIDUpdate = () => {props.handleBought(props.groceryInfo._id, props.groceryInfo.name);}const sendIDDelete = () => {props.handleDelete(props.groceryInfo._id, props.groceryInfo.name);}return (<div className="conatainer mt-1 mb-1" id="groceryitem"><div className="row"><div className="col-sm d-flex justify-content-start"><button className="btn btn-success" onClick={sendIDUpdate}>Got It!</button></div><div className="col-sm">{props.groceryInfo.name}</div><div className="col-sm">{props.groceryInfo.quantity}</div><div className="col-sm d-flex justify-content-end"><button className="btn btn-danger" onClick={sendIDDelete}>Dont Need Anymore</button></div></div></div>);}export default GroceryItem;

Open the GroceryList.js file and add the following code:

import React, { useState, useEffect } from 'react';import axios from 'axios';import AddGrocery from './AddGrocery';import GroceryItem from './GroceryItem';function GroceryList() {const groceryService = axios.create({baseURL: '/api'});const [groceries, setGroceries] = useState([]);const [statusMessage, setStatusMessage] = useState({ message: '' });useEffect(() => {getGroceries();}, []);const getGroceries = async () => {const { data } = await groceryService.get(`/groceries/all`);setGroceries(data);};const updateGrocery = async (id, name) => {const data = { bought: true }await groceryService.patch(`/groceries/update/${id}`, data);setStatusMessage({ message: 'Got ' + name });getGroceries();}const deleteGrocery = async (id, name) => {await groceryService.delete(`/groceries/delete/${id}`);setStatusMessage({ message: 'Removed ' + name })getGroceries()}return (<><AddGrocery handleUpdate={getGroceries} /><div className="container"><div className="card"><div className="card-header"><h3>Grocery List</h3>{statusMessage.message}</div><div className="card-body"><ul className="list-group">{groceries && groceries.filter(grocery => grocery.bought === false).map(filteredGrocery => (<GroceryItem groceryInfo={filteredGrocery} handleBought={updateGrocery} handleDelete={deleteGrocery} />))}</ul></div></div></div></>);}export default GroceryList;

In the App.js file delete all the code between the div with classname=App

In the now empty div add the following code:

<Switch><Route exact path='/' component={GroceryList} /></Switch>

In App.js find the line:

import { Switch, Route } from 'react-router-dom';

Add the following below the above line:

import GroceryList from './components/GroceryList';

CSS Styling

In the frontend → src folder find the file called App.css and add the following to the bottom:

#groceryitem {border-style: solid;border-color: black;}

Test the Frontend and Backend together

Ensure all files are saved

In a terminal pointing to the root directory of the project, type the following command:

$ npm start

As before this will start the backend running on localhost. Leave this terminal open and open a second terminal.

In a second terminal pointing to the frontend folder of the project, type the following command:

$ npm start

This will start the frontend running on localhost. A new browser window should automatically open and direct to http://localhost:3000 but if that does not happen you can navigate there manually.

If you get errors when trying to start the frontend they will be displayed in the terminal. Troubleshoot the errors until you are able to successfully start the frontend.

In the browser test that the app functions as expected. You should be able to input new groceries into the list, which will insert them into the database, mark them bought, which will update the database or remove them, which will delete them from the database.

The next part of the series will deal with deploying the app to a Kubernetes cluster.

--

--

No responses yet