react-part-2

Web Development with React For Beginners – Part 2

By Rasyue | On December 3, 2021

Welcome to Web Development with React For Beginners – Part 2.

Web Development with React For Beginners – Part 2 – Introduction

If you are here without going thru the first part. I strongly recommend you to read the first part here at Web Development with React For Beginners

If you have done so, then let’s continue on with the first part.

First thing first, let’s look into React Router.

Web Development with React For Beginners- Adding Router

First, let’s look at how we can build our routes.

Go ahead and install the react-router-dom module. You can read more here

npm install history@5 react-router-dom@6

If you are wondering why do we need to install this module, let me explain.

When you build an application with React, basically what you are building is a single-page application(SPA).

Essentially, there is no such thing as pages in React. A React application is made up of multiple number of React components.

Why We Use react-router ?

To allow us to navigate between these components, we will need to use the react-router module which is a React standard library that will handle these operations which are:

  1. Allow navigation between React components that will return a view.(Remember that some components do not return a view will some do depending on its use case).
  2. Allow us to change the browser URL through the usage of BrowserRouter. This will allow us to sync our UI with the URL. Keep in mind that when the browser URL changes, only the component changes which will then return a different view, we don’t actually changing pages.

I hope that clear out your confusion and answer any question that you have. Let’s continue with our main task. Developing our website!

As of this writing, we are using react-router version 6.

Open you index.js and paste the followings.

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

/* add this line */
import { BrowserRouter } from "react-router-dom";

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

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

Now, create two new files and name them as Home.js and About.js

Paste below for Home.js

export default function Home(){


    return(
        <>
            <h1>Home Page</h1>
        </>
    )
}

Paste below for About.js

export default function About(){


    return(
        <>
            <h1>About Page</h1>
        </>
    )
}

The Home.js will serve as our Home view while the About.js will serve as our About view. Import these two components into App.js

import './App.css';
import { Routes, Route, Link } from "react-router-dom";
import Home from './Home.js'
import About from './About.js'

function App() {
  return (
    <div className="App">
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="about" element={<About />} />
      </Routes>
    </div>
  );
}

export default App;

You should have something like this after refreshing your application.

rasyue react home page
home page

In your browser, enter localhost:3000/about and you should see this.

rasyue about page
about page

Congrats! You just successfully created two React components to display as views.

Don’t you find it hard to have to manually write your route in the browser search?

Hmm what better way do we have to make this little problem go away?

What we need right now is a navigation bar.

Web Development with React – Adding Navigation Bar

To make things easier, we need to install react-bootstrap module. Keep in mind that you don’t really have to use bootstrap. There are tons of UI module out there for you to explore. Go crazy!

npm install react-bootstrap bootstrap@5.1.3

Open your index.js and import bootstrap css

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { BrowserRouter } from "react-router-dom";
/* add this line */
import 'bootstrap/dist/css/bootstrap.min.css';

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

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

Now, create a new file name NavBar.js and paste the followings.

import {Nav, Navbar, Container} from 'react-bootstrap'
import { Link } from "react-router-dom";

export default function NavBar(){


    return(
        <>
            <Navbar bg="light" expand="lg">
                <Container>
                    <Navbar.Toggle aria-controls="basic-navbar-nav" />
                    <Navbar.Collapse id="basic-navbar-nav">
                    <Nav className="me-auto">
                        <Nav.Item style= {{marginRight: 15}}>
                            
                                <Link to="/">Home</Link>
                            
                        </Nav.Item>

                        <Nav.Item>
                            
                                <Link to="/about">About</Link>
                            
                        </Nav.Item>
                    </Nav>
                    </Navbar.Collapse>
                </Container>
            </Navbar>
        </>
    )
}

Now, import this NavBar component into Home.js and About.js

Home.js

import NavBar from './NavBar.js'


export default function Home(){


    return(
        <>
            <NavBar />
            <h1>Home Page</h1>
        </>
    )
}

About.js

import NavBar from './NavBar.js'



export default function About(){


    return(
        <>
            <NavBar />
            <h1>About Page</h1>
        </>
    )
}

Refresh and test out the new navbar that we just created.

rasyue home page with navbar
home page with navbar

Looking neat huh?

Now, what else?

Ahh! A website can never be complete without a footer!

Web Development with React – Adding A Footer

First, create a new file Footer.js and then paste the followings.



export default function Footer(){


    return (

        <footer className="text-sm px-8 text-center flex-none py-4 bg-dark">
        
            <p className = "text-light">My Footer</p>
        </footer>
    )

}

Now import this Footer function into Home.js and About.js

Home.js

import NavBar from './NavBar.js'
import Footer from './Footer.js'

export default function Home(){


    return(
        <>
            <NavBar />
            <div style = {{minHeight: 800, marginTop: 20 }}>
                <h1>Home Page</h1>
            </div>
            <Footer />
        </>
    )
}

About.js

import NavBar from './NavBar.js'
import Footer from './Footer.js'


export default function About(){

    return(
        <>
            <NavBar />
                <div style = {{minHeight: 800, marginTop: 20 }}>
                    <h1>About Page</h1>
                </div>
            <Footer />
        </>
    )
}

You should have something like when you refresh your application.

react home page with navbar and footer
home page with navbar and footer

There you have it, your very own React website. We will add more complex stuff starting from now. However, before that, as an exercise, I want you to add a couple more components and routes. Go ahead, try it and see if you can get it right.

The next step will be to learn about Protected Routes and Unprotected Routes.

Web Development with React – Protected and Unprotected Routes

What does it means by Protected and Unprotected Routes?

Have you ever been to a website that only allows you to go certain pages while some other pages will require you to login first?

Take Facebook for an example, before you can go to your profile or home page, you will need to login first into your account before it redirects you to your profile page.

In this situation, your profile page is the protected route while the page where you login is the unprotected route.

If you were to define these two terms, it will simply be that unprotected routes are routes where it is openly accessible by any user that comes to your website.

On the other hand, protected routes are routes that are only accessible to a single or a number of users.

We usually grant access to users/user access to a protected routes after they have logged in(asking the user to log in is the simplest way for you to determine the authenticity of a user).

Web Development with React – How Does React Keep Routes Protected?

To better understand this, we first need to understand three completely separate concepts.

The localStorage, React Context API and state management.

It is very important for you to understand these three concepts so that you can better understand React.

localStorage is a web browser property that allows you to save a key-value pair data in the web browser. The localStorage is usually use to store information like token after user authentication/login.

React Context API is a React API that allows developer to pass data through the component tree. Much like props but with React Context API you don’t have to pass it from one component to another component (parent/child).

On the other hand, state management is a concept that of sharing data between components. We talked about component state and lifecyle in the previous post but these two are only for internal use of that very component.

By using state management tools, we will be able to share data across components quickly and precise. You might not be able to picture this but imagine a very big and complex application, only using props and Context just doesn’t cut it. Another reason of using state management tools is because it persist the data stored inside it.

We will talk more about React Context and state management in our next post.

Web Development with React For Beginners – Using localStorage to make protected routes.

First, create a new file, Auth.js and paste the followings.

import {
    Navigate ,
    useLocation
  } from "react-router-dom";



export const setToken = (token) =>{

    // set token in localStorage
    localStorage.setItem('rasyueToken', token)

}

export const fetchToken = (token) =>{

    // fetch the token
    return localStorage.getItem('rasyueToken')

}



export function RequireToken({children}) {

    
    let auth = fetchToken()
    let location = useLocation();
     

    // if no token set in localStorage, redirect user
    if (!auth) {
      
      return <Navigate to="/" state={{ from: location }} />;
    }
    

    // return all children route
    return children;
}
   

Next, create a new file name Profile.js and paste the followings.

import NavBar from './NavBar.js'
import Footer from './Footer.js'
import {useNavigate} from "react-router-dom";
import {fetchToken} from './Auth.js'

export default function Profile(){
    const navigate = useNavigate();

    const signOut = () => {

        localStorage.removeItem('rasyueToken')
        navigate("/");
    }

    return(
        <>
            <NavBar />
                <div style = {{minHeight: 800, marginTop: 20 }}>
                    <h1>Profile Page</h1>

                    <p>Hi, {fetchToken()} . This is your profile</p>

                    <div>
                        <button type = 'button' onClick= {signOut}>Sign Out</button>
                    </div>
                </div>
            <Footer />
        </>
    )
}

Open Home.js and paste the followings.

import NavBar from './NavBar.js'
import Footer from './Footer.js'
import {useState} from 'react'
import {setToken, fetchToken} from './Auth.js'
import {useNavigate} from "react-router-dom";

export default function Home(){
    const navigate = useNavigate();
    const [username, setUsername] = useState('');

    const login = () =>{

       setToken(username)
       navigate("/profile");
    }

    return(
        <>
            <NavBar />
            <div style = {{minHeight: 800, marginTop: 20 }}>
                <h1>Home Page</h1>

                <div style = {{marginTop: 50 }} >
                    {
                        fetchToken() 
                        ? (
                            <p>You are logged in!</p>
                        ) 
                        : (
                            <form>
                            <label style = {{marginRight: 10 }}>Input Username: </label>
                                <input type = 'text'  onChange={ (e)=> setUsername(e.target.value)} />
                            <button type = 'button' onClick = {login}>Login</button>
                        </form>
                        )
                    }
                   

                </div>

            </div>
            <Footer />
        </>
    )
}

Next, we will need to modify Navbar.js a bit to add Profile component.

Open Navbar.js and paste the followings.

import {Nav, Navbar, Container} from 'react-bootstrap'
import { Link } from "react-router-dom";

export default function NavBar(){


    return(
        <>
            <Navbar bg="light" expand="lg">
                <Container>
                    <Navbar.Toggle aria-controls="basic-navbar-nav" />
                    <Navbar.Collapse id="basic-navbar-nav">
                    <Nav className="me-auto">
                        <Nav.Item style= {{marginRight: 15}}>
                            
                            <Link to="/">Home</Link>
                            
                        </Nav.Item>

                        <Nav.Item style= {{marginRight: 15}}>
                            
                            <Link to="/about">About</Link>
                            
                        </Nav.Item>
                        <Nav.Item>
                            
                            <Link to="/profile">Profile</Link>
                            
                        </Nav.Item>
                    </Nav>
                    </Navbar.Collapse>
                </Container>
            </Navbar>
        </>
    )
}

Finally, open App.js and paste the followings.

import './App.css';
import {
  Route,
  Routes,
} from "react-router-dom";

import Home from './Home.js'
import About from './About.js'
import Profile from './Profile.js'
import {RequireToken} from './Auth.js'

function App() {

  return (
    <div className="App">
      <Routes>
       
        <Route path="/" element={<Home />} />
        <Route path="about" element={<About />} />
        <Route
          path="/profile"
          element={
            <RequireToken>
              <Profile />
            </RequireToken>
          }
        />
      </Routes>
    </div>
  );
}


export default App;

And we are done. Refresh and try it out.

Try to login with any username.

 home page login rasyue react
home page with login form

When you click login, it will set the username into the localStorage

We will then use this value to allow access to protected route, in this case the Profile component is protected.

 rasyue react profile view
profile view when logged in

You will be automatically redirected to the Profile view after logging in.

Upon pressing Sign Out button, the code will clear out the localStorage value that we set when logging in and redirect you back to the Home view.

There you have it, a simple protected route using localStorage.

The End but not Really..

To summarize, in this post we learned about react-router, we learned about creating multiple views/pages and components, we also learned about protected routes along with localStorage, React Context API and state management.

In the next part, we will be learning about how we can communicate to the database with React and lots of other exciting stuff.

Stay tuned!

Leave a Reply

Your email address will not be published. Required fields are marked *

*

*
*