Build your first ReactJS app
It's as easy as typing...create-react-app
What is ReactJS & How do I learn it
In frontend development, ReactJS (also known as React.js/React) is used to build User Interfaces (UIs). To learn React, I followed a similar approach as I did with other programming languages, which was to create simple projects that grew into larger, more complex projects, learn by doing approach.
You have an idea for a simple web app, and you’re excited to bring it to life through code. With so many different tools to bring your idea to life, you’ve decided that using ReactJS as the framework is the most suitable tool for this project, but why?
In my programming journey, I chose ReactJS as one of the first frameworks I learned, not only because it has a lot of popularity, but also because it makes creating different parts of a project easier through reusable code called react-components. Components allow you to reuse the same piece of code without having to write it again, they are the core of the app. As your projects become more complex in design and functionality, this property becomes more useful.
The image above represents an illustration of react-components.
The purpose of this guide is to walk you through the process of building your very first ReactJS app, an ingredients list app, which I built using the framework for the first time. The guide assumes some basic knowledge of HTML, CSS & JavaScript and is useful for those working in a local development environment.
What you need
Make sure you have NodeJS, and NPM installed on your machine
Code editor, I use Visual Studio Code (VScode)
The plan
Getting started: Start your ReactJS environment with
create-react-app
Let’s start coding: Design the components
Tell the World - You built your first ReactJS app
Getting started
Several ways exist to get started building a ReactJS app, one of which is creating a boilerplate using a program called create-react-app. This will set up all the packages, files, and folders you need to get started developing your app. Using create-react-app requires Node Package Manager (NPM) installed on your machine.
Reminder (ᵔ◡ᵔ): if any of the tools mentioned above are new to you and you don’t have them installed yet, that’s ok, you can read about how to download & set them up by clicking on the name to navigate to their respective install guides.
Step 1:
- inside your CLI create a new project folder called “first-react-app“ (you can give it any name you prefer), by running
npx create-react-app first-react-app
- if prompted to confirm you do indeed want to install the program, type “y“ or “yes“ to confirm.
The installation process may take a few minutes, you can use the time to grab a cup of your favourite beverage while it completes ☕. In the directory you chose to install create-react-app in, you should see a new folder called "first-react-app". In my case, it's located in C:\Users\skogsglänta
.
Step 2:
Open that folder inside your text editor (I’m using VScode), from your CLI you can type
cd ..first-react-app
code .
code . tells the CLI you want to open VScode
Reminder (ᵔ◡ᵔ): don’t forget that (.) dot
The folder structure should look similar to this:
The above is a snapshot of the default folder structure.
Subfolder walkthrough default code:
- the public folder contains a simple HTML file that serves as the single-page application
- the src folder will contain all the components you will build for the app
Step 3:
In the code editor or CLI type npm start
to start the development server, which should open the development build on http:localhost://3000 (if this does not happen automatically, you could also copy and paste the URL into the browser).
The above is an illustration of terminal: start dev server
Step 4:
Remove all code & files that aren’t required i.e default comments and logos from App.js
, your folder structure and code should look similar to the snippet below…
Let’s start coding
Among the features of the app are a header with a navigation menu, a form for adding list items, and a section for items that already exist, with a checkbox for striking them through and a delete button.
Step 1: In the src folder create a new folder called components
Step 2: Inside the components folder create two new folders called layout and pages respectively
Step 3: Still within the components folder create three files called AddIngredient.js, IngredientName.js, Ingredients.js
After making the new changes, your folder structure should resemble the one below:
- Step 4: Inside the …/src/components/layout/ create a new file and call it Header.js, this file will serve as the apps header component. Add the code below:
import React from 'react';
import { Link } from 'react-router-dom';
function Header() {
return (
<header style={headerStyle}>
<h1 style={titleStyle}>Ingredient List</h1>
<Link style={linkStyle} to="/" >Home</Link> | <Link style={linkStyle} to="about">About</Link> | <Link style={linkStyle} to="budget">Budget</Link> | <Link style={linkStyle} to="shops">Shops</Link>
</header>
)
}
const headerStyle = {
background: '#45046a',
color: '#f1ebbb',
textAlign: 'center',
padding: '20px'
}
const linkStyle = {
color: '#ccc',
textDecoration: 'none',
fontSize: "30px"
}
const titleStyle = {
fontSize: "46px"
}
export default Header;
- Step 5: In …/src/components/pages/ create three files, and call them
About.js
,Budget.js
, andShops.js
, these will serve as the About, Budget and Shop components.
Inside the About.js
add the code below:
import React from 'react'
export function About() {
return (
<React.Fragment>
<h1 style={titleStyle}>About</h1>
<p style={paraStyle}>This is the Ingredients App v1.0.0. It is my first React.js application. *(sajustsmile)*</p>
</React.Fragment>
)
}
const titleStyle = {
marginLeft: "20px",
fontSize: "38px",
}
const paraStyle = {
marginLeft: "20px",
fontSize: "26px",
}
export default About;
Inside the Budget.js
add the code below:
import React from 'react'
export function Budget() {
return (
<React.Fragment>
<h1 style={titleStyle}>Budget</h1>
<p style={paraStyle}>This is the budget section of the app.</p>
</React.Fragment>
)
}
const titleStyle = {
marginLeft: "20px",
fontSize: "38px",
}
const paraStyle = {
marginLeft: "20px",
fontSize: "26px",
}
export default Budget;
Inside the Shops.js
add the code below:
import React from 'react';
export function Shops() {
return (
<React.Fragment>
<h1 style={titleStyle}>Shops</h1>
<p style={paraStyle}>Shops that sell these ingredients.</p>
<ul style={shopStyle}>
<li>Store Name: REWE,
Location: Prenzlauer Berg</li>
<li>Store Name: Netto,
Location: Ku'Damm</li>
<li>Store Name: Aldi
Location: Charlottenburg</li>
</ul>
</React.Fragment>
)
}
const shopStyle = {
marginLeft: "20px",
fontSize: "26px",
}
const titleStyle = {
marginLeft: "20px",
fontSize: "38px",
}
const paraStyle = {
marginLeft: "20px",
fontSize: "26px",
}
export default Shops;
Having implemented the above code, you have just created the UI for your first-react-app, now to add the extra functionalities that give it the list characteristics.
- Step 6: In …/src/components/**AddIngredient.js add the code below:
import React, { Component } from 'react';
import PropTypes from 'prop-types';
export class AddIngredient extends Component {
state = {
name: ''
}
onSubmit = (e) => {
e.preventDefault();
this.props.addIngredient(this.state.name);
this.setState({ name: '' })
}
onChange = (e) => this.setState({ [e.target.name]: e.target.value});
render() {
return (
<form onSubmit={this.onSubmit} style={{display: 'flex'}}>
<input
type="text"
name="name"
style={{flex: '10', padding: '15px', fontSize:"20px"}}
placeholder="Add Ingredient..."
value={this.state.name}
onChange={this.onChange}
/>
<input
type="submit"
value="Add Item"
className="btn"
style={{flex: '1', fontSize:"20px"}}
/>
</form>
)
}
}
AddIngredient.propTypes = {
addIngredient: PropTypes.func.isRequired
}
export default AddIngredient;
What does the code above do? It creates a form so users can input text (list items) that gets added to the app as ingredients when they click the add button.
- Step 7: In …/src/components/**IngredientName.js add the code below:
import React, { Component } from 'react';
import PropTypes from 'prop-types';
export class IngredientName extends Component {
getStyle = () => {
return {
background: '#9bdeac',
padding: '15px',
fontSize: '26px',
borderBottom: '2px #fbfd8a dotted',
textDecoration: this.props.ingredient.inPantry ?
'line-through' : 'none'
}
}
render() {
const { id, name } = this.props.ingredient;
return (
<div style={this.getStyle()}>
<p>
<input type="checkbox" onChange={this.props.actionComplete.bind (this, id)} />
{ '' }
{ name }
<button onClick={this.props.delIngredient.bind(this, id)} style={btnStyle}>✘</button>
</p>
</div>
)
}
}
// PropTypes
IngredientName.propTypes = {
ingredient: PropTypes.object.isRequired
}
const btnStyle = {
background: '#c70039',
color: '#fff',
border: 'none',
padding: '6px 9px',
borderRadius: '20%',
cursor: 'pointer',
float: 'right',
marginTop: "5px"
}
// PropTypes
IngredientName.propTypes = {
ingredient: PropTypes.object.isRequired,
actionComplete: PropTypes.func.isRequired,
delIngredient: PropTypes.func.isRequired,
}
export default IngredientName;
The code above essentially creates the delete button for an ingredient already on the list.
- Step 8: In …/src/components/**Ingredients.js add the code below:
import React, { Component } from 'react';
import IngredientName from './IngredientName';
import PropTypes from 'prop-types';
class Ingredients extends Component {
render() {
return this.props.ingredients.map((ingredient) => (
<IngredientName key= {ingredient.id} ingredient={ingredient} actionComplete={this.props.actionComplete} delIngredient={this.props.delIngredient}/>
));
}
}
// PropTypes
Ingredients.propTypes = {
ingredients: PropTypes.array.isRequired,
actionComplete: PropTypes.func.isRequired,
delIngredient: PropTypes.func.isRequired,
}
export default Ingredients;
The code above is the function that creates or adds the ingredients to the list.
Step 9: The next step is to work on the
App.js
file, which is the root component of the app and handles all its components. Static pages in the app are served fromApp.js
, and in our app, they would be Header, Ingredients, AddIngredient, About, Budget, and Shops. The hierarchy here is important because whichever position component is placed will determine how it is rendered.In …/src/**App.js add the code below:
/* Designed & coded by Sandra Ashipala <https://github.com/sandramsc> */
import React, { Component } from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import Header from './components/layout/Header';
import Ingredients from './components/Ingredients';
import AddIngredient from './components/AddIngredient';
import About from './components/pages/About';
import Budget from './components/pages/Budget';
import Shops from './components/pages/Shops';
import { v4 as uuidv4 } from 'uuid';
import './App.css';
class App extends Component {
state = {
ingredients: [
{
id: uuidv4(),
name: 'Chicken Mince (Keema)',
inPantry: false,
},
{
id: uuidv4(),
name: 'Samosa Patti',
inPantry: false,
},
{
id: uuidv4(),
name: 'Green chillies',
inPantry: false,
},
{
id: uuidv4(),
name: 'Coriander leaves',
inPantry: true,
},
{
id: uuidv4(),
name: 'Turmeric Powder',
inPantry: false,
},
{
id: uuidv4(),
name: 'Garam Masala Powder',
inPantry: true,
},
{
id: uuidv4(),
name: 'Ginger Garlic Paste',
inPantry: false,
},
]
}
// Action Complete
actionComplete = (id) => {
this.setState({ ingredients: this.state.ingredients.map(ingredient => {
if(ingredient.id === id) {
ingredient.inPantry = !ingredient.inPantry
}
return ingredient;
}) });
}
// Delete Ingredient
delIngredient = (id) => {
this.setState({ ingredients: [...this.state.ingredients.filter(ingredient => ingredient.id !==id)] });
}
// Add Ingredient
addIngredient = (name) => {
const newIngredient = {
id: uuidv4(),
name,
inPantry: false
}
this.setState({ ingredients: [...this.state.ingredients, newIngredient] });
}
render() {
return (
<Router>
<div className="App">
<div className="container">
<Header />
<Route exact path="/" render={props => (
<React.Fragment>
<AddIngredient addIngredient={this.addIngredient} />
<Ingredients ingredients={this.state.ingredients} actionComplete={this.actionComplete}
delIngredient={this.delIngredient} />
</React.Fragment>
)} />
<Route path="/about" component={About} />
<Route path="/budget" component={Budget} />
<Route path="/shops" component={Shops} />
</div>
</div>
</Router>
);
}
}
export default App;
- Step 10: In the final step, we add additional styling to the app inside the
App.css
, which should also be imported into theApp.js
file as you can see in the code snippet above.
/* Designed & coded by Sandra Ashipala <https://github.com/sandramsc> */
@import url("https://fonts.googleapis.com/css2?family=Caveat&display=swap");
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: "Caveat", cursive;
font-size: 18px;
line-height: 1.4;
padding: 0;
}
a {
color: #333;
text-decoration: none;
}
.container {
padding: 0 1rem;
}
.btn {
display: inline-block;
border: none;
background: #fdb827;
color: #fff;
padding: 7px 20px;
cursor: pointer;
}
.btn:hover {
background: #ffd369;
}
Tell the world
That's it for this guide, if you'd like to take a look at the code repository on GitHub, you can find it here. Why not share your new app with others or host it on GitHub or Bitbucket for other developers to view and perhaps contribute to your code (^ ‿ ^) !
I am continuing to learn more about the ReactJS framework and other programming languages, and the more I practice software development, I have found that the best way for me to learn has been to simply keep practising coding alongside understanding the code that I write and other programmers write.
When developing apps in general or in the future, you might find it useful to read the official documentation for the specific tool/language to acquire more knowledge on implementation and usage. It is a habit that I have embraced along my journey, and with software being updated so frequently, it is necessary to be aware that technical documentation exists for us to utilize.
Note ✍🏼: Understanding the code you are interested in implementing is always a good practice, rather than simply copying and pasting. In the event that you encounter a bug when copying and pasting someone else’s code, it will make it more difficult to understand its origin..and as a result, finding a solution (fixing the bug) will be more like playing hide and seek with a blindfold on...in the dark.
If you followed through till the end and built along great job! See, getting started with ReactJS is as easy as typing...create-react-app⚛️.
Thank you for reading. Happy coding!