React Hands on, Part 1

Dec 18th 2019 by Mattes Wieben

First React application: Hands on

Introduction 

Superheroes need challenges. Otherwise, they might get bored and behave like Hancock. So let’s make sure, this doesn’t happen. Therefore, we are going to create a small Task-Creation-Application for all the people living in Coding-Valley. Today we’ll only care about the frontend, which we’re going to use React for. If you’re not familiar with the concepts and ideas behind React I recommend reading this theoretical introduction first. (LINK)

Motivation

Why react?

But Why

Because it is an awesome framework to built frontends. It really is a lot of fun to write React code. Besides that it is pretty wide spread. But I'll write about that in a separate post. For now I'll conclude my answer with the companies who use it:

Airbnb, Uber, Facebook (I mean obviously, they created it), Netflix, Instagram, Twitter, Reddit (https://stackshare.io/react) ... nuff said

And why do I need to publish another tutorial whilst there are a bazillion other tutorials out there?

Another one

Firstly, I wanted to get into React myself. Since teaching stuff is one of the best ways to really learn the ins and outs of something, it seemed obvious to me to create my own little tutorial.

Secondly, writing a tutorial is an awesome example to create a fun but absolutely useless app. I mean, how often did you want to create a task for a super hero?

Lastly, my vision for this blog contains to be a collection of tutorials about all the technological stuff I like 😊

Step 0: Project Setup

If you don’t care about the setup, skip this step and fetch the first commit from the github-repo https://github.com/mats-codes/task-creator. I tried to remind myself of comitting after each step. But I might have forgotten one or two

I'll do better next time. I promise.

Back to business ..

Prerequisites:

  • Node >= 8.10

  • npm >= 5.6

Setup

As soon as you set those tools up on your machine, open the terminal/cmd and navigate to the folder in which you want to create your project. Executing the following command will setup a project for you:

npx create-react-app <app-name>

<app-name> should be replaced with the name you want to give your application. In our case it’ll be ticket-creator. After the creation we simply navigate into the created folder and run the application:

cd <app-name>

npm start

If your browser doesn’t start automatically, open it and head to http://localhost:3000. Congrats, this is your very first React-App! Now open the application-folder in an IDE of your choice and we’re ready to implement our application.

Project Structure

Before we get into coding, let’s have a look at the project structure:

-node_modules

-public

-src

.gitignore

package-lock.json

package.json

README.md

  • Package.json and package-lock.json: The package.json and package-lock.json files are used by Node. We don’t really care about them right now.

  • node_modules folder: Node stores the downloaded dependencies here.

  • .gitignore-file: This file is for specifying folders and files which you don’t want to be pushed to your git-repo.

  • Readme: Documentation of commands you can use to build, test and run your app.

Nothing React-specific so far… 

In the public folder, there are only two important files. As you might have already guessed, one of them is the index.html. After a quick scan through the file we’ll find a root element:

<div id="root"></div>

That’s where React is going to hook in. The manifest.json is used to tell react, which differences you want to see between a mobile and a desktop client. For now, empty the “icons”-array in the manifest.json to avoid errors later on. The other files in the public folder aren’t relevant for us and can be deleted.

The src-folder will contain all the source-code written by us. We won’t need anything but App.js, App.test.js and index.js. So go ahead and delete the rest. Furthermore, change the file-content of index.js to:

import React from 'react';

import ReactDOM from 'react-dom';

import App from './App';

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

and from App.js to:

import React from 'react'; 

function App() {

 return (

   <div className="App">

     <header className="App-header">

       Hello Coding-Valley. You'll be secure soon.

     </header>

   </div>

 );

export default App;

Step 0 done. Your application’s code should look like this(LINK) by now.

Step 1: Breaking our UI into a component hierarchy

There is another step before we can get our hands on some code. We need to break the UI that we want to build into its building bricks, its components. At this point it doesn’t matter, if we got a template from our designer or if the design is up to us. We just need to make sure to have a clear vision of our UI. In this specific case our UI will look like this:

UI Vision

After a little thinking we might come up with a component structure like this:

UI Vision with components

Note, that there is not really a right or wrong when splitting a UI up into components. However, my rule of thumb is: The more complex our components grow the less optimal is my split. Try to apply the Single-Responsibility-Pattern for components just as if you were thinking about splitting your code into functions or classes. 

Usually, considering our data model will help as well. Assuming we modelled our data correctly, the structure of our UI should match the structure of our data. If that seems like nonsense to you right now, just wait until we implemented the business-logic next week, it’ll become a lot clearer then.

It might feel a little clunky in the beginning to accept all the overhead when creating separate files and classes or functions for all those components, but it’ll be very worth your time when your application starts to grow. Everything will be a lot easier to reuse and debug.

I chose not to create own components for the elements of the search bar, the list, the input-field, and the textarea, because the components would only be wrappers for a single React-Element. At some point the overhead becomes bigger than the benefit of small components. If you feel the app becomes more readable like that go ahead and get some practice in by extracting the elements into own components after finishing this tutorial.

Now that we know the direction, let’s finally get our hands dirty and hack some code.

Step 2: Building a static version of our app

Adding some style

Actually my plan was to use plain React for this tutorial. But believe me when I say, it gets ugly. Real ugly. At one point during the development of this app, this is what I looked at:

Ui Fail

Yes, you may laugh. Not really, what you were looking for, when you were searching for a React Tutorial, right?

That’s why that was the moment when I took a step back and decided to use a framework to make the UI look better. Therefore, our first development task will be to add the material ui-core from google. Head to your terminal/cmd and execute:

npm install @material-ui/core

and afterwards add:

<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" />

anywhere inside the <head> tag in your index.html. That’s it. Speaking react we added some components developed by google, which we can use in our app now. If you’re not familiar with components by now, give me one more minute to explain.

index.js

Now let’s have a look at our index.js. It should look like this:

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

In other words that means: “Hey React, search our document for a DOM-Element with id=”root” and render our App-Component in there”. Remember the root-tag in the index.html. That’s it.

App

The App-Component used in the index.js is imported from the App.js-file. It is a React convention to start components with capital-letters which is why our filename, as well as the function name, starts with a capital “A”.

In this file, we create a React Component. A component’s purpose is to split the UI in smaller parts (like we did theoretically in the previous chapter). Basically, a component should behave like a pure function, accepting props as parameter and offering a render-method that returns one React-Element. This method is called by React whenever React needs to update and rerender the UI.

More precisely we create a Function Component called App(). This function accepts one parameter, props (more about that next week) and returns exactly one React Element. That means a function component is solely made up by the render-method. React-Elements are the smallest building-blocks, which React Apps are made of. They are:

  • Used to build more complex components (Which than in fact can be used as Elements for building even more complex Components)

  • Plain JavaScript Objects (Big difference to DOM-Elements)

Since those React Elements are plain JavaScript objects, we can assign them to variables and pass them around as function arguments as we like. React takes care of mapping our ReactDOM to the actual DOM, which we should never touch! Since React is clever, it only updates those parts of the DOM, that really need to change. Also, JS objects are a lot easier and faster to create than DOM-Objects. Those two facts are two of the main reasons, why React is such a blazing-fast library. Even Flash would have trouble keeping up with the pace.

Flash

Our App.js should look like this:

AppJS

A short step-by-step-explanation, what we are doing:

  1. we specify the function (line 18)

  2. we return a div-element (line 22)

  3. we add a headline to our application (line 28)

  4. we add our SearchBar (line 36)

  5. we add our TaskTable line (line 39)

  6. we add our TaskCreationForm (line 45)

  7. we add some lines for styling (grey)

  8. we export the app (line 55)

Does the notation look weird to you? It is called JSX, React’s syntax extension to JS, which you should use to tell React, what you want to see in the browser. Under the hood JSX creates React-Elements. Those elements are then used by React to update the UI whenever the render-method is called.

Any expression can be added in curly braces, which enables you to use the full power of JavaScript. By using this notation React lets you split up your application by concerns instead of technologies. That is useful for debugging, since you don’t need to switch between HTML and JS files when searching for that nifty bug. You rather have everything in one place.

Searchbar

Other than Function-Components, React offers the possibility to create Class Components. The main difference between class-components and function components is that class-components can contain a state. We’ll talk about that next week. Furthermore, a class component may contain functions other than the render-function. That enables class components to implement more complex business logic.

SearchBar

By now, the mindful reader might wonder what the difference between a function component and the render-method of a class-component is. There is none.

TaskTable

From here on it gets a little repetitive, so that I’ll shorten it up for your reading pleasure. If you feel bored, skip the explanations and just have a look at the code.

The TaskTable is a Class-Component. For now, nothing but the render-function is needed. It returns a <div>-element. This <div>-element contains a header (line 9) and a list (lines 10-20). For the time being, we are adding some mock-tasks - just to see something and make sure our static UI works. Actually, they should be added by our users. We’ll fix that next week.

Tasktable

TaskCreationForm

The TaskCreationForm is a Class-Component. For now nothing but the render-function is needed. It returns a <div>-element. This <div>-element contains:

  • a header (line 16)

  • a textinput (lines 18-21)

  • a textarea (lines 24-29)

  • our HeroSelector (line 32)

  • our SeveritySelector (line 35)

  • and an Add-Button (lines 38-40)

  • Everything else is just for styling (greyed out).

TaskCreationForm

HeroSelector

The HeroSelector is a Class-Component. For now, nothing but the render-function is needed. It returns a <div>-element. This <div>-element contains a label (line 11) and a Select-Element (lines 12-18) with three heroes as select options (lines 15-17). For the time being, we are adding our heroes as hard-coded strings. Actually, they should be dynamically added. We’ll fix that next week.

HeroSelector

Don’t worry that the UI won’t update when you try to change the content of the select. We didn’t implement state yet. Also something, we’ll fix next week.

SeveritySelector

The SeveritySelector is a Class-Component. For now, nothing but the render-function is needed. It returns a <div>-element. This <div>-element contains a Radio-Group Element (lines 13-29) with three Radio-Buttons (lines 14-28) - one for each possible severity of the task.

SeveritySelector

In lines 17, 22 and 27, you can see examples of passing a React-Element as parameter.

You can click it and it won’t change state. Again, don’t worry. We’ll fix that next week.

Round up

That was it for today. You can find the current version of our application here (LINK). We learned the basics of React and how to create a beautiful UI using the material-ui components provided by google. By now we should know about:

  • How to set a React project up

  • JSX

  • Elements

  • Components (Function- and Class-)

  • Render-method

Next week we’ll add the logic to our application which will enable our users to create actual tasks. Therefore, we’ll need:

  • State

  • Props

  • One-Way-Dataflow

  • Event-Handling

Thank you so much for reading! I hope you enjoyed it and I would appreciate any kind of feedback. If anything stayed unclear, please feel free to drop a question in the comments. Also, if I made any mistakes, let me know and I’ll be very happy to learn something and correct them as soon as possible. See you next week!

Share this post