Loading...

A quickstart tutorial on React

This is an easily digestable guide for those who would like to get a React application up and running quickly mixed with production considerations


Setup

Dependencies

Installing node and NPM
                                    
                                        $ sudo apt-get update
                                        $ sudo apt-get install nodejs
                                        $ sudo apt-get install npm
                                    
                                

If there are any problems follow this link here
Explanation: Node is a runtime environment for Javascript (allows you to run javascript code), NPM short for node package manager basically allows for easy access and updates of code modules (packages). More about npm

Project Initialization and NPM modules

Package to create react app template
                                    
                                        $ npm install -g create-react-app                       
                                    
                                

The create-react-app package allows one to create a working template of a react app.
The app contains the following dependencies (other packages/modules)
react - essential to build a react app
react-dom - essential to built a react app
react-scripts - used to run the application in your browser for testing and debugging
You can create the sample application by running

                                    
                                        $ create-react-app sample-app                        
                                    
                                

Here I used "sample-app" as the name of my application you can use whatever your like.
You can test the application by navigating to the root directory for the application e.g. "sample-app" and running

                                    
                                        $ npm start                        
                                    
                                

The browser should open to the application running on localhost:3000

Fresh Start

Restructuring

We want to start from nothing so we're going to remove all the previous code, remove all the current files from the src folder.

                                    
                                        $ rm -rf src/*                        
                                    
                                

In the src folder Create two new files index.html and index.js
We're going to create a basic web page and link the javascript file.

                                    
                                        <!DOCTYPE html>
                                        <html>
                                        <head>
                                            <title> MySite :) </title>
                                        </head>
                                        <body>
                                        
                                        </body>
                                        <script type="text/javascript" src="index.js"></script>
                                        </html>                      
                                    
                                

React Basics

Components I

What is React ?

There are very many fanciful and technical definitions which you can google, for now i'll say it in a simple manner using my own words

React is a framework that specializes on building an application using reuseable parts called Components that you create and customize.

What is a component ?

Components are the building blocks for react
A component can be thought of as a custom element that you create, for a simple example, consider the following

                                    
                                        <h1> Bork Bork, I am hungry </h1>                      
                                    
                                

Suppose we wanted to create an 'element' that would always do this, well that's where components come in, we can create a component to do just that.
In your index.js file, insert the following.

                                    
                                        import React,{Component} from 'react';

                                        class Dog extends Component{
                                            render(){
                                                return(<h1>Bork Bork, I am hungry</h1>);
                                            }
                                        }                     
                                    
                                
React is the entry point to the React library. If you load React from a <script> tag, these top-level APIs are available on the React global. If you use ES6 with npm, you can write import React from 'react'. If you use ES5 with npm, you can write var React = require('react').
- React docs

To put it simply, the React library allows you to use Components which gives you the ability to create 'custom elements' that you can reuse.
The Component class's fundamental method is render. Simply, the render method should return what you would like on your page.

render, render ? React-Dom

Up till now we haven't actually put anything onto our page, it's time to change that, using React-Dom. React-Dom as the name implies, allows us to interact with the DOM. The bread and butter of this library is it's own render method, which actually puts whatever is given to it on the page. The previous render method was part of the Component class and acted as the output for that specific Component while this render method takes whatever is given to it and spits it on the page wherever you specify.

Let's see how it works, first we need to create a place to put our component so we're going to add a div with the id root, edit your index.html to look like the following

                                    
                                        <!DOCTYPE html>
                                        <html>
                                        <head>
                                            <title> MySite :) </title>
                                        </head>
                                        <body>
                                            <div id="root"> </div>
                                        </body>
                                        <script type="text/javascript" src="index.js"></script>
                                        </html>                      
                                    
                                

Now we're going to import the render function from the react-dom library and render it in the div we just added, edit your index.js to look like the following

                                    
                                        import React,{Component} from 'react';
                                        import {render} from 'react-dom';

                                        class Dog extends Component{
                                            render(){
                                                return(<h1>Bork Bork, I am hungry</h1>);
                                            }
                                        }                   

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

Note that either render function must only have a single root element.
If you do not already have your application running you can do so by running

                                    
                                        $ npm start                        
                                    
                                

The browser should open to the application running on localhost:3000

Side step into JSX ?

It may seem confusing to see HTML code in your javascript file, this is because we are using JSX.

JSX is a preprocessor step that adds XML syntax to JavaScript.
- React docs
JSX allows you to naturally add HTML structure through javascript. (note we can use react without JSX however it's not the best idea imo)

JSX allows you embed expressions i.e. put in javascript variables and manipulate them in the HTML. You can do this with the use of curly braces { }

                                    
                                        import React,{Component} from 'react';
                                        import {render} from 'react-dom';

                                        class Dog extends Component{                                            
                                            render(){
                                                let speech = "Bork Bork, I am hungry";
                                                return(<h1>{speech}</h1>);
                                            }
                                        }   

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

Try changing the text for speech to see if it works :^)

Components II

State mate

state is an object that stores the state of a component and is defined in it's constructor method. You can access it by conventional methods.
In the following, we are going to define speech in the Component's state and give it the text we'd like displayed.

                                    
                                        import React,{Component} from 'react';
                                        import {render} from 'react-dom';

                                        class Dog extends Component{   
                                            constructor(){
                                              super();
                                              this.state = {
                                                speech: "Bork Bork, I am a doggie :)"
                                              }
                                            }

                                            render(){        
                                                return(<h1>{this.state.speech}</h1>);
                                            }
                                        }   

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

Things to note, you should call super(); at the start of your constructor, it allows acces of props
state is simple javascript object and speech is just a property.
The way we accessed speech was this.state.speech

Props man

props are the properties you want to pass to your Component. There are a few ways in which people pass props however the fundamental principle is that a prop is passed to a Component as an attribute.
In the following example I am going to pass what I would the Dog Component is going to say using a prop that I will name woof.

                                    
                                        import React,{Component} from 'react';
                                        import {render} from 'react-dom';

                                        class Dog extends Component{   
                                            constructor(props){
                                              super();
                                              this.state = {
                                                speech: props.woof
                                              }
                                            }

                                            render(){        
                                                return(<h1>{this.state.speech}</h1>);
                                            }
                                        }   

                                        render(<Dog woof="Bork Bork, I am a good doggie :)"/>, document.getElementById('root'));                  
                                    
                                

Things to note;
We passed in what our doggo is saying using the attribute woof <Dog woof="Bork Bork, I am a good doggie :)"/>
The constructor method accepted props constructor(props)
props is a simple object and woof is just a property accessed as usual props.woof

Updating state

We update a Component's state using the setState method. "Why can't we just set the state directly ?", well the setState method has triggers that cause the component to be re-rendered for the new values. To put it simply, if we use setState the component is automatically updated for us in the DOM.
To show how this works, we're going to create an input box that allows us to update text for our Dog Component. We're going to (1) add an input box, (2) define some function to update the state with the text from the box.

                                    
                                        import React,{Component} from 'react';
                                        import {render} from 'react-dom';

                                        class Dog extends Component{   
                                            constructor(props){
                                              super();
                                              this.state = {
                                                speech: props.woof,
                                              }
                                            }

                                            textChanged = (e) =>{
                                              this.setState({speech:e.target.value})
                                            }

                                            render(){        
                                              return(
                                                  <div>
                                                    <h1>{this.state.speech}</h1>
                                                    <input onInput={this.textChanged} type="text"/>
                                                  </div>
                                              );
                                            }

                                        }   

                                        render(<Dog woof="Bork Bork,I am a good doggie :)"/>, document.getElementById('root'));   
                                    
                                

We created a function textChanged to update the state's property speech with whatever the user inputs. We also added an input field and used it's onInput attribute to call our textChanged function, note that the input element and the onInput attribute are default HTML.
If you're paying attention, there is one more thing we changed, we put a div around the h1 and input tags. This is because there must be a single root element for the render function.

A bit closer to the Standard

The usual way to do things; the entire application is usually one Component using other smaller Components that you create (which may use other smaller Components that you create, compoception :o )
Okay spread em, we'll leave our index.js for our main app component and put a the Dog component in a new file Dog.js.
Create Dog.js and make it look like this

                                    
                                        import React,{Component} from 'react';

                                        export default class Dog extends Component{   
                                            constructor(props){
                                              super();
                                              this.state = {
                                                speech: props.woof,
                                              }
                                            }

                                            textChanged = (e) =>{
                                              this.setState({speech:e.target.value})
                                            }

                                            render(){        
                                              return(
                                                  <div>
                                                    <h1>Bork Bork,{this.state.speech}</h1>
                                                    <input onInput={this.textChanged} type="text"/>
                                                  </div>
                                              );
                                            }

                                        }     
                                    
                                

Now time for index.js, we're going to create a new component to represent our app and we'll call it App

                                    
                                        import React,{Component} from 'react';
                                        import {render} from 'react-dom';
                                        import Dog from './Dog.js';

                                        class App extends Component{
                                          render(){
                                            return(
                                              <div>
                                                <Dog woof="I need petting" />
                                              </div>
                                            );
                                          }

                                        }

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

Try to create a simple Cat component on your own in a file Cat.js, i'll put a sample below in case you're feeling a bit lazy =/.

                                    
                                        import React, {Component} from 'react';

                                        export default class Cat extends Component{
                                            constructor(){
                                                super();
                                            }

                                            render(){
                                                return(
                                                    <h1> Meow :) </h1>
                                                );
                                            }

                                        }
                                    
                                

Now make the required edits to your index.js file to import our Cat component and render it

                                    
                                        import React,{Component} from 'react';
                                        import {render} from 'react-dom';
                                        import Dog from './Dog.js';
                                        import Cat from './Cat.js';

                                        class App extends Component{
                                          render(){
                                            return(
                                              <div>
                                                <Dog woof="I need petting" />
                                                <Cat />
                                              </div>
                                            );
                                          }

                                        }

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

React Application Essentials

Routing

Installing react-router-dom

There is only one HTML page so how exactly does one present different views or give the illusion of 'pages', how do we go about routing different views based on user selections. The intuition is to have components that represents views (pages) and load components based off what the user selects.
To help us achieve this we are going to use a library called react-router-dom. This is an external library to react therefore we need to download and add it to our project, we can do this using npm

                                    
                                        npm install react-router-dom --save
                                    
                                
BrowserRouter and Route

There are two main components to consider for routing however we'll only be focusing and using the Component BrowserRouter. BrowserRouter acts the mastermind behind your routing, since we're swapping components rather than loading pages, BrowserRouter tracks your 'location' and saves 'browsing history' within the application.
The BrowserRouter swaps components and memorizes the order of swaps but how do we actually define the routes i.e. what path => what component, well the Route component does exactly that.
We're going to define a route for our Dog component and another for our Cat component, edit your index.js too look like the following

                                    
                                        import React,{Component} from 'react';
                                        import {render} from 'react-dom';
                                        import Dog from './Dog.js';
                                        import Cat from './Cat.js';
                                        import { BrowserRouter, Route, Link } from 'react-router-dom';

                                        class App extends Component{
                                          render(){
                                            return(
                                              <BrowserRouter>
                                                <div>
                                                  <Route path="/dog" component={Dog}/> 
                                                  <Route path="/cat" component={Cat}/>
                                                </div>
                                              </BrowserRouter>
                                            );
                                          }

                                        }

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

We changed the components Dog and Cat with the Route component. In the Route component, we specified the path in the path property and the component to load in the component attribute, weird right ( ͡° ͜ʖ ͡°).
We then wrapped everything in the BrowserRouter component, note that BrowserRouter only expects a single child.
Run your application then navigate to localhost:3000/cat and localhost:3000/dog.

Links

Let's create a simple menu to link to our routes.

                                    
                                        import React,{Component} from 'react';
                                        import {render} from 'react-dom';
                                        import Dog from './Dog.js';
                                        import Cat from './Cat.js';
                                        import { BrowserRouter, Route, Link } from 'react-router-dom';

                                        class App extends Component{
                                          render(){
                                            return(
                                              <BrowserRouter>
                                                <div>
                                                  <Route path="/dog" component={Dog}/> 
                                                  <Route path="/cat" component={Cat}/>

                                                  <ul>
                                                    <li> <a href="/dog">dog</a> </li>
                                                    <li> <a href="/cat">cat</a> </li>
                                                  </ul>
                                                </div>
                                              </BrowserRouter>
                                            );
                                          }

                                        }

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

This triggers a browser refresh each time a link is clicked, this is bad because we already have everything we need loaded, this means our application can run much faster. To solve this we replace the anchor tags with the Link component. The Link component acts just as the anchor tag would but without the page refresh.

                                    
                                        import React,{Component} from 'react';
                                        import {render} from 'react-dom';
                                        import Dog from './Dog.js';
                                        import Cat from './Cat.js';
                                        import { BrowserRouter, Route, Link } from 'react-router-dom';

                                        class App extends Component{
                                          render(){
                                            return(
                                              <BrowserRouter>
                                                <div>
                                                  <Route path="/dog" component={Dog}/> 
                                                  <Route path="/cat" component={Cat}/>

                                                  <ul>
                                                    <li> <Link to="/dog">dog</Link> </li>
                                                    <li> <Link to="/cat">cat</Link> </li>
                                                  </ul>
                                                </div>
                                              </BrowserRouter>
                                            );
                                          }

                                        }

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

Take a look at our Dog component, while everything does work, an initial statement is missing for our doggo. We've not passed in any woof property. Let's look at our Route component, we need to pass in more than just a bare component Dog, for this we can use the render property.
The render property works similarly to the component property in that it tells the Route component what needs to be on the page however, the render property allows more flexibility. The render property accepts a function that must return what is to be rendered, meaning you can write and do whatever you like in that function.

                                    
                                        import React,{Component} from 'react';
                                        import {render} from 'react-dom';
                                        import Dog from './Dog.js';
                                        import Cat from './Cat.js';
                                        import { BrowserRouter, Route, Link } from 'react-router-dom';
                                        class App extends Component{
                                          render(){
                                            return(
                                              <BrowserRouter>
                                                <div>
                                                  <Route path="/dog" render={ 
                                                    ()=>{
                                                      return <Dog woof={"I can speak for myself"}/>
                                                    } 
                                                  }/> 
                                                  <Route path="/cat" component={Cat}/>

                                                  <ul>
                                                    <li> <Link to="/dog">dog</Link> </li>
                                                    <li> <Link to="/cat">cat</Link> </li>
                                                  </ul>
                                                </div>
                                              </BrowserRouter>
                                            );
                                          }

                                        }

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

In our Route component, we simply replaced the component property with the render property which accepts a function that returns something to be rendered. We wrote a function that returns our Dog component with a woof property and of course we wrapped that between curly braces.
We can tidy up a little for some more complexity, since the render property accepts a function, we can define a function outside and simply return that function.

                                    
                                        import React,{Component} from 'react';
                                        import {render} from 'react-dom';
                                        import Dog from './Dog.js';
                                        import Cat from './Cat.js';
                                        import { BrowserRouter, Route, Link } from 'react-router-dom';
                                        class App extends Component{
                                          render(){

                                            let func = ()=>{
                                              return(<Dog woof={"I can speak for myself"}/>);
                                            }
                                            return(
                                              <BrowserRouter>
                                                <div>
                                                  <Route path="/dog" render={func}/> 
                                                  <Route path="/cat" component={Cat}/>

                                                  <ul>
                                                    <li> <Link to="/dog">dog</Link> </li>
                                                    <li> <Link to="/cat">cat</Link> </li>
                                                  </ul>
                                                </div>
                                              </BrowserRouter>
                                            );
                                          }

                                        }

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

Now our func function is too small so we're gonna add some more stuff to justify pulling it out.

Simple Route Restriction

I only want authorized individuals to see my Dog component, what should we do ? (secret doggo). Well to begin, we need something to indicate whether or not our user is authorized or not, for that we're going to add a property authorized to our state. Then in our func function, depending on if a user is authorized or not, we shall allow them to access our doggo.
Our func function however SHOULD definitely return some sort of view, therefore we're going to create a simple AccessDenied component to return if a user does not have access.

First our AccessDenied component in AccessDenied.js.

                                    
                                        import React,{Component} from 'react';

                                        export default class AccessDenied extends Component{
                                            render(){
                                                return(
                                                    <div> 
                                                        <h1>Access Denied</h1>
                                                        <img src="http://www.free-icons-download.net/images/dog-icon-86470.png" alt="dog pic"/>
                                                    </div>
                                                )
                                            }
                                        }
                                    
                                

Now to modify our index.js

                                    
                                        import React,{Component} from 'react';
                                        import {render} from 'react-dom';
                                        import Dog from './Dog.js';
                                        import Cat from './Cat.js';
                                        import AccessDenied from './AccessDenied.js';
                                        import { BrowserRouter, Route, Link } from 'react-router-dom';
                                        class App extends Component{
                                          constructor(){
                                            super();
                                            this.state={
                                              authorized:0
                                            }
                                          }

                                          render(){

                                            let func = ()=>{
                                              if(this.state.authorized)
                                                return(<Dog woof={"I can speak for myself"}/>);
                                              else
                                                return(<AccessDenied/>);
                                            }

                                            return(
                                              <BrowserRouter>
                                                <div>
                                                  <Route path="/dog" render={func}/> 
                                                  <Route path="/cat" component={Cat}/>

                                                  <ul>
                                                    <li> <Link to="/dog">dog</Link> </li>
                                                    <li> <Link to="/cat">cat</Link> </li>
                                                  </ul>
                                                </div>
                                              </BrowserRouter>
                                            );
                                          }

                                        }

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

(Note: There are more complex ways to do this but for now this is effective and simple.)

Requests

Choosing a library

React has no native way to make requests, therefore we need to use a javascript library to make these requests for us. There are several options, just to give some context, two of the most popular would be an old but gold JQuery and one of the more popular newer guys fetch, we'll be using neither ( ͡° ͜ʖ ͡°). We shall be using one of the middle-age guys axios which is very popular and powerful.

Let's install axios

                                    
                                        npm install axios --save   
                                    
                                

We'll just be making simple requests as there are many better tutorials that focus solely on axios, now let's look at some of the syntax

                                    
                                        axios.get(url)              //url of resource you're trying to get 
                                        .then(function(response){   //function to handle a successful response from the server

                                        }).catch(function(err){     //function to handle a unsuccessful response from the server

                                        })
                                    
                                

Let's grab a simple json file from on the server and print it to console, you can put the following code at the buttom of your index.js then remove it after testing it out

                                    
                                        axios.get('https://steffanboodhoo.github.io/sample_data.json')
                                        .then(function(resp){
                                          console.log(resp)
                                        })
                                    
                                

Let's create one more component, List, in a file List.js. We're going to render a simple list with the data we fetch using axios.

                                    
                                        import React,{Component} from 'react';

                                        export default class List extends Component{
                                            constructor(){
                                                super();
                                                this.state={
                                                    items:[]
                                                }
                                            }

                                            render(){
                                                return(
                                                    <div>
                                                    </div>
                                                )
                                            }
                                        }
                                    
                                

This is the basic skeleton where we define some state to be used later and return an empty div, now in the constructor we're going to load some data using axios.

                                    
                                        import React,{Component} from 'react';
                                        import axios from 'axios';

                                        export default class List extends Component{
                                            constructor(){
                                                super();
                                                this.state={
                                                    items:[]
                                                }

                                                axios.get('https://steffanboodhoo.github.io/sample_data.json')
                                                .then((resp)=>{
                                                    this.setState({items:resp.data})
                                                });
                                            }

                                            render(){
                                                return(
                                                    <div>
                                                    </div>
                                                )
                                            }
                                        }
                                    
                                

We've imported the axios library and used it to fetch some data and update our state with it. Now we're going to use that data to create our list.

                                    
                                        import React,{Component} from 'react';
                                        import axios from 'axios';

                                        export default class List extends Component{
                                            constructor(){
                                                super();
                                                this.state={
                                                    items:[]
                                                }

                                                axios.get('https://steffanboodhoo.github.io/sample_data.json')
                                                .then((resp)=>{
                                                    this.setState({items:resp.data})
                                                });
                                            }

                                            render(){
                                                let func = ()=>{
                                                    let elems = []
                                                    for(let i in this.state.items)
                                                        elems.push(<h1>{this.state.items[i].first_name}</h1>);  
                                                    return elems;
                                                }
                                                return(<div>{func()}</div>)
                                            }
                                        }
                                    
                                

Important things to note, React elements can be stored in variables e.g. let elem = <h1> doggo </h1>;, these same elements can be used in rendering using the curly braces e.g. (<div>{elem}</div>.
Using these two concepts, we were able to create a function func to loop through the data and create an array of elements. We then called func inbetween the div which returned a list of elements to be rendered.
At this point you should be able to link this component on your own with a route or otherwise, give it a shot :^(click me)
(Consider making the call in the containing component, App, then passing the data to be rendered in props then use array.map to create your list of elements)

Closing remarks

There are a lot more complex topics and methods to be covered, I may cover in a follow up (depending on time, feedback etc). I really enjoyed doing this, I tried to make is as easily digestable while covering practical methods and understanding. Anyways if you have gone though this, please let me know what you think and if there are any errors or what topics/projects/tools you'd like to see me do cao m8s