In this tutorial, I am going to walk you through creating your very own shopping list app using ReactJS. The main function of this app is to add items to your checklist as well as delete them whenever you are through with your items.
The first thing you have to do is make sure your development environment can run ReactJS.
- First, you need to download and install NodeJS
- Second, you need to get a text editor, such as Sublime Text or Notepad++
- Finally, create a folder that will store all of your ReactJS projects.
Creating the base of the app
Open your terminal/command line prompt and change directories to the project folder that you just created. Once you are here, enter the following command:
[code]create-react-app ShoppingList[/code]
This command creates your new web app and displays some commands that you can use to manipulate your new project. Enter the command:
[code]npm start[/code]
as it will run your project in the background while you work. Once that is done, navigate over to the “public” and “src” folders within your project and delete everything contained within them.
Next, open up your text editor and create a new HTML file called “index” then save that file to your public folder. Add the following content to your “index.HTML” file:
[html]<!doctype html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width" >
<title>Shopping List</title>
</head>
<body>
<h1 style="text-align:center;">Shopping List</h1>
<div id="container">
</div>
</body>
</html>
[/html]
This code gives you the basic structure for your web app. Next, create a new file called “index.css” and save that to the “src” folder in your project directory. Then add the following code:
[css]body {
padding: 50px;
background-color: #C0392B;
font-family: sans-serif;
}
#container {
display: flex;
justify-content: center;
}[/css]
This file will add some styling to the skeleton of your app. Feel free to personalize your app by changing the font or by changing the “background-color” hex code value in your “index.css” file. Next, create another file in your “src” folder called “index.js” then add the following code:
[html]import React from "react";
import ReactDOM from "react-dom";
var destination = document.querySelector("#container");
ReactDOM.render(
<div>
<p><ShoppingList/></p>
</div>,
destination
);[/html]
By now, you will have noticed that your web app compiles and runs automatically whenever you save your files. At this point, your blog should look similar to this:
Molding the user interface
As it stands we only have the base of our app up and running so now lets work on creating the User Interface by adding more core elements. In your “src” folder, create a “ShoppingList.js” file then copy the following code into that file:
[html]import React, { Component } from "react";
class ShoppingList extends Component {
render() {
return (
<div className="ShoppingListMain">
<div className="header">
<form>
<input>
</input>
<button type="submit">Add</button>
</form>
</div>
</div>
);
}
}
export default ShoppingList;
[/html]
Now the app is beginning to take shape. Navigate back to our “index.js” and reference our new file using the “import” statement at the top of the file:
[code]import ShoppingList from "./ShoppingList";
[/code]
If you look at your app now, it should be similar to this:
Now you should be able to type into your text field and click on the “add” button. However, since we haven’t added any functionality to those actions, nothing will be carried out.
Adding items to our list
Next, let’s add some event handlers to our project so that text can be added to our list. Find the <form> tag in our “ShoppingList.js” file and add the following:
[html]
<form onSubmit={this.addItem}>
[/html]
In the form element, we are waiting and listening for the ‘submit’ action to occur and when it does we call the ‘addItem’ method to populate our list with text. But before we see anything, we need to define more methods. In the same file, add the following code about the render() method:
[html]constructor(props) {
super(props);
this.addItem = this.addItem.bind(this);
}
addItem(e) {
}
[/html]
So now we have defined our addItem method, but that doesn’t mean the action is ready to be executed. Next, add the following state object to the constructor class we just created:
[html]this.state = {
items: []
};[/html]
This will hold the visual representation of our app at any given point when an action is triggered. Next, we have to make sure that all the values that are read into our “input” element are stored in our “items” array. Within the same file, scroll down to your render() method and add the following line:
[html]<input ref={(a) => this._inputElement = a}
placeholder="Item Name">[/html]
This reference associates our input values to a property for our “addItem” method to use. Scroll up to the file and update our “addItem()” method with the following code:
[html]addItem(e) {
if (this._inputElement.value !== "") {
var newItem = {
text: this._inputElement.value,
key: Date.now()
};
this.setState((prevState) => {
return {
items: prevState.items.concat(newItem)
};
});
this._inputElement.value = "";
}
console.log(this.state.items);
e.preventDefault();
}[/html]
Let’s examine what is going on in this section. The new variable we just created passes through an object that contains the input and a unique key value associated with each item. The following code makes it so that each individual state object is not accidentally modified by assigning each their own array. Lastly, we clear our input value for the next shopping item.
The next step in our project is to create a new component, “ShoppingItems”, which passes our items array as a property in the render() method of our “ShoppingList.js” file:
[html]</div>
<ShoppingItems entries={this.state.items}
</div>
[/html]
Then add the following import statement to make sure all the files are connected:
[code]import ShoppingItems from "./ShoppingItems";[/code]
Next, create a new file in your “src” directory called “ShoppingItems.js” which will hold the “ShoppingItems” component that we created earlier. Copy and paste the following code:
[html]import React, { Component } from "react";
createTasks(item) {
return <li key={item.key}>{item.text}</li>
}
render() {
var shoppingEntries = this.props.entries;
var listItems = shoppingEntries.map(this.createTasks);
return (
<ul className="theList">
{listItems}
</ul>
);
}
};
[/html]
Looking at the code, the render() method breaks down our input items into readable syntax and the createTasks() method stores a list of the input items. Everything is sorted according to the unique key values we assigned earlier in the project. What is finally returned is the list of everything item that you entered. Your web app should look similar to this:
To make our web app more appealing, let’s add some styling to it. Create a new file “ShoppingList.css” then copy and paste the following code:
[css]
.ShoppingListMain .header input {
padding: 10px;
font-size: 16px;
border: 2px solid #FFF;
width: 165px;
}
.ShoppingListMain .header button {
padding: 10px;
font-size: 16px;
margin: 10px;
margin-right: 0px;
background-color: #34495E;
color: #FFF;
border: 2px solid #34495E;
}
.ShoppingListMain .header button:hover {
background-color: black;
border: 2px solid black;
cursor: pointer;
}
.ShoppingListMain .theList {
list-style: none;
padding-left: 0;
width: 250px;
}
.ShoppingListMain .theList li {
color: #FFF;
background-color: rgba(52,73,94);
padding: 15px;
margin-bottom: 15px;
border-radius: 5px;
transition: background-color .2s ease-out;
}
.ShoppingListMain .theList li:hover {
background-color: black;
cursor: pointer;
}
ul.theList {
padding: 0;
}[/css]
When your web app refreshes you’ll notice that the input field, button, and list have all been styled to make them look more professional. Here, you have a lot of flexibility so be sure to customize this code to your preference. Once your CSS file is ready, go back to your “ShoppingList.js” file and add this reference at the top:
[code]import "./ShoppingList.css"[/code]
Deleting items from our list
Finally, let’s move on to our last functional task which is to add the action to delete items from your list. Essentially we are going to set it up so that an item is automatically deleted when you click on it. First, we need to define a new handler for this action in the “ShoppingItems.js” file by updating the createTasks() method with the following code:
[html]createTasks(item) {
return <li onClick={() => this.delete(item.key)}
key={item.key}>{item.text}</li>
}
[/html]
This updated method now listens for a screen click which in turn will initiate the delete method. In this same file, scroll up and paste the following code:
[html]constructor(props) {
super(props);
this.createTasks = this.createTasks.bind(this);
}
delete(key) {
this.props.delete(key);
}[/html]
This is the first step in setting up the delete functionality for your web app. Now head back to the ShoppingList.js file because we need to add the delete property to our render() method:
[html]</div>
<ShoppingItems entries={this.state.items}
delete={this.deleteItem}/>
</div>
[/html]
Now our delete method from the ShoppingItemst.js file is fully connected with the component in this file. It is now time to define our deleteItem() method to our ShoppingList component:
[html]deleteItem(key){
var filteredItems = this.state.items.filter(function (item) {
return (item.key !== key);
});
this.setState({
items: filteredItems
});
}[/html]
This method passes in the unique key value and checks it against all the items in the filler method. Next, the method creates a new array called filteredItems which stores all the items except for the item we want to delete. Finally, the ‘this.setState’ methods tell our UI to update itself display which item has been removed from our list. Now head over to your “ShoppingList.js” file and add the following line to your constructor class:
[html]this.deleteItem = this.deleteItem.bind(this);[/html]
This makes sure that all the references are linked to their appropriate targets. That is it for our core application. Now create a new file called “ShoppingList.css” and add the following code:
[css].ShoppingListMain .theList li {
color: #FFF;
background-color: rgba(52,73,94);
padding: 15px;
margin-bottom: 15px;
border-radius: 5px;
transition: background-color .2s ease-out;
}
.ShoppingListMain .theList li:hover {
background-color: black;
cursor: pointer;
}[/css]
This code adds color to our list and also adds a hovering effect when your cursor is over an item in the list. Lastly, our final task is to add some animation to our creation and deletion of items from our list. Luckily for us, React’s community has already created tons of libraries for us to use. First, go back to our command line prompt and type in the following:
[code]npm i -S react-flip-mov[/code]
Then go to your “ShoppingItems.js” file and the following import command:
[code]import FlipMove from "react-flip-move";[/code]
Finally, add the following code to the bottom of the file:
[html]render() {
var shoppingEntries = this.props.entries;
var listItems = shoppingEntries.map(this.createTasks);
return (
<ul className="theList">
<FlipMove duration={250} easing="ease-out">
{listItems}
</FlipMove>
</ul>
);
}
};[/html]
Once that is done, your web app is finally complete. If you wish to deploy your web app online, I recommend using this resourceful Firebase install and deployment guide. Your finished product should look similar to the following image.
ReactJS is a very useful tool that can help build appealing Web Apps for your business. If you have any questions about using ReactJS or building Web Apps with ReactJS send us an email!
Photo by Fotis Fotopoulos on Unsplash