Creating a Single Page Web Application with React and ES6

I wrote an article about “Creating a RESTful Web API with Node.js and Express.js from scratch”. This article was showing just a backend api side of an example todo list application. You can find out more about this web api by following above link.

In this article, I am gonna show you how to create a Single Page Web App with ReactJS. So we are gonna develop a Todo App by consuming RESTful Web API I have shown before. You can assume this article as part-2.

I have also published and documented this web api on heroku. You can explore it by following this url;
https://todowebapi.herokuapp.com

This article assumes you have basic javascript knowledge and terminal using capabilities.

You can find the source code of this app at this github repository.

We will use javascript ES6 syntax and we need to compile and bundle our source codes to distribute and run the app. It means we need tools such as babel and webpack and some configuration stuff. But I think that this step is so overcomplicated to become a part of this article. So I am gonna create a new article later about this step I mentioned above. Now we can skip this step.

But how can we handle the step we spoke above?

If you don’t have experience about that configuration step mentioned above, you can use “crate-react-app" toolchain. It creates a frontend build pipeline for us. Under the hood, it uses babel and webpack, but you don’t need to know anything about them for now.

Let’s start to create the application.

Before start

If you have never used Node.js or npm package manager you should install them.

You don’t need Node.js to run React app but you will need Node.js installed on your computer in order to use npm package manager.

To check whether the Node.js is already installed on your computer, open your terminal and run “node -v" command. If you see your Node.js version it's installed. Otherwise go to below link.

Click here to download and install Node.js (You can choose LTS version)

And if you don’t have any IDE or text editor for writing javascript I advice you Visual Studio Code.

Click here to download VS Code (Optional)

Creating Project

Go to your workspace root folder and run below command to create a new React app;

npx crate-react-app todo-app-with-react-es6

It will create a new react application in your workspace named “todo-app-with-react-es6” then install required modules and packages.

When you open the “todo-app-with-react-es6” folder with your favorite IDE you will see an initial project structure including some html markup and images.

I am gonna override them and edit “src/App.js" file to create our application start page.

Here is my current folder structure after removing some unnecessary files and assets;

/todo-app-with-react-es6|-- node_modules
|-- public
| `-- index.html
|-- src
| |-- App.js
| |-- App.test.js
| |-- index.css
| |-- index.js
| |-- serviceWorker.js
| `-- setupTests.js
|-- .gitignore
|-- package.json
`-- README.md

And below html markup is enough for our index.html file.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Todo App with React and ES6</title>
</head>
<body>
<div id="root"></div>
</body>
</html>

We are gonna start with a small initial screen code in order to reduce complexity because of that our “App.js" and "index.css" files look like below for now.

import React from 'react';

class App extends React.Component {
render() {
return (
<div className="app-container">
<h1>Todo List</h1>
</div>
);
}
}

export default App;

And “index.css" file;

body {
margin: 0;
}

.app-container {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
color: white;
}
a {
color: #fff;
text-decoration: none;
}

a.selected {
color: #DC143C
}

After editing above files open your terminal in the "todo-app-with-react-es6" folder and run "npm start" command.

You will see just “Todo List” header text. Don’t worry this is expected result :)

Getting Items

As our header text says now we have to get todo items from our Web API.

Todo items response of our web api looks like below.

[
{"id": 1, "title": "Finalize project"},
{"id": 2, "title": "Book ticket to London"},
{"id": 3, "title": "Finish last article"},
{"id": 4, "title": "Get a new t-shirt"},
{"id": 5, "title": "Create dinner reservation"}
]

We will make some changes in our “App.js" code to fetch and list todo items.

I put heroku address I have published and mentioned before as web api url. But you can also run the web api in your local after clone or download.

import React from 'react';

class App extends React.Component {
constructor(props) {
super(props);

this.state = {
items: []
};

this.todoApiUrl = 'https://todowebapi.herokuapp.com';
}

componentDidMount() {
fetch(`${this.todoApiUrl}/items`)
.then(response => response.json())
.then(items => this.setState({items}));
}

render() {
return (
<div className="app-container">
<h1>Todo List</h1>

<ul>
{
this.state.items.map(item => <li key={item.id}>{item.title}</li>)
}
</ul>
</div>
);
}
}

export default App;

We have 3 important point in the above code.

One of them is componentDidMount() method which is invoked after a react component is ready. Reactjs official documents says; "If you need to load data from a remote endpoint, this is a good place to instantiate the network request." We got it :)

Another point is our state object you see inside the constructor of our Component class. It holds the data fetched from the remote endpoint. Give your attention at the “this.setState({items})" expression in the last chained function of the fetch operation. It means that put fetched items in the state object after the fetch operation completed.

And now we have the data in the state object so we can render it on the screen in the render() method. You can pass your component template to the render() method as you see above. But as you can see markup of the component is not just plain html. There is a javascript statement inside of the braces. It is called as JSX which is special syntax for describing the react components UIs. It's neither html nor javascript but it's funny :)

Every time you call this.setState function and update your state object your component's view will be re-render with your new state object.

Creating New Item

So let’s add a couple of new ui component and let the user to create a new todo item.

import React from 'react';

class App extends React.Component {
constructor(props) {
super(props);

this.state = {
items: [],
title: ''
};

this.todoApiUrl = 'https://todowebapi.herokuapp.com';

this.createNewItem = this.createNewItem.bind(this);
}

componentDidMount() {
fetch(`${this.todoApiUrl}/items`)
.then(response => response.json())
.then(items => this.setState({items}));
}

createNewItem() {
fetch(`${this.todoApiUrl}/items`, {
method: "POST",
headers: new Headers({'Content-Type': 'application/json; charset=utf-8'}),
body: JSON.stringify({title: this.state.title})
}).then(response => {
if (!response.ok) {
alert('An error occurred while creating new item');
} else {
return response.json();
}
}).then(createdItem => {
this.setState(prevState => ({
items: [...prevState.items, {id:createdItem.id, title: createdItem.title}],
title: ''
}));
});
}

render() {
return (
<div className="app-container">
<h1>Todo List</h1>

<ul>
{
this.state.items.map(item => <li key={item.id}>{item.title}</li>)
}
</ul>

<div>
Title: <input type="text" value={this.state.title} onChange={(event) => this.setState({title: event.target.value})} />
<button onClick={this.createNewItem}>Add New</button>
</div>
</div>
);
}
}

export default App;

You see a new html input and button control at the bottom of the list. It must have caught your attention that we handle onchange event of the html input control. This is the way of reactjs to getting current input value.

This inline function makes sure holds input value in the title field of the state object. If you want to understand in depth how to handle html components in reactjs, you can look at the “Forms” section of the reactjs official docs.

And we have a new createNewItem() function which is sending a POST request with a new item title to the web api. We invoke this function when we click "Add New" button.

Our web api gives us the created item object as server response if everything is ok. Then we put the successfully created item as well into the state object to make sure showing it on the screen.

Updating and Deleting Selected Item

Now we are gonna add new features for selecting, editing and deleting items. Latest source code of "App.js" is below.

We put a new “selectedItemId” field in the state object which will be set when you click an item on the screen. And we wrapped each item with a clickable html link which is setting “selectedItemId” field with id of clicked item. And we set a specific css class on the selected item to highlighting selected item. This developments makes items selectable on screen.

As you can see “updateSelectedItem()" and "deleteSelectedItem()" functions are very similar to "createNewItem()" function as we spoke above. Only difference is they have own http verb according to what they do.

Thank you for your time and patience.

Full Stack Developer

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store