Using React Router for optimizing React apps

Using React Router for optimizing React apps

In this tutorial, we will discuss a popular routing library used with React applications known as React Router

In this tutorial, we will discuss a popular routing library used with React applications known as React Router

React is often used for building single page applications (SPAs). SPAs tend to have multiple page views. When navigating from one-page view to another, reloading the entire page view is a tedious and not so efficient task. In fact, it diminishes the benefits of a SPA. To work as it should, a SPA must render parts of views when required instead of reloading the entire page.

Routing comes into the picture when navigating from one page to another in a SPA app. Routing can be categorized in two ways. Static and dynamic. SPAs follow dynamic approach.

Table of Contents

  • Requirements
  • Getting Started
  • First Route with React Router
  • What is BrowserRouter?
  • The Link Component
  • Active Links with NavLink
  • Adding Parameters to the Routes
  • Connecting Crowdbotics support to Your Github Repo
  • Conclusion
Requirements
  • NodeJS v8.x.x or higher installed along with npm/yarn
  • create-react-app installed globally to on your local dev machine generate a new React project

Bonus: You can also, use npx to generate a new React project without installing create-react-app.

Getting Started

To create a new React project run the following command at the desired location on your local machine.

create-react-app react-router-v4-demo

Once the project is generated, traverse inside the newly created directory. This strategy is the default way to generate a new React app.

React Router as a library contains three different npm packages.

  • react-router
  • react-router-dom
  • react-router-native

Each of the packages has a different use case. The first one, react-router is the core package and is used with the next two packages listed above. The react-router-dom has to be used when building a web application. This is what we are going to use in this tutorial. The last one, react-router-native tends to be used in a React Native application.

To add React Router in the React app, execute the following command from a terminal window.

yarn add react-router-dom

Please note that, for the rest of the tutorial, we will be using yarn as the JavaScript package manager to add or remove dependencies. If you wish to use npm, there is no one stopping you.

To run the React app, go to the terminal window and execute the command npm start. This will start the development server. You will be welcomed by the default boilerplate project screen in a web browser window on URL [http://localhost:3000/](http://localhost:3000/ "http://localhost:3000/").

First Route with React Router

To create the first route in the React app, let us import BrowserRouter from react-router library.

import React from "react"
import { BrowserRouter as Router, Route } from "react-router-dom"

To create a route, we use from the ```react-router-dom```. This is where the logic of routing is placed. It renders the UI of a component. A has a prop called path which is always matched with the current location of the app. On the basis of this prop, the desired component gets rendered. When the component is not getting rendered, Routereturns null. The component name is also passed as prop component. Look at the below snippet.

function App() {
   return (
       
           
       
   )
}

There is the functional App component that returns a BrowserRouter which holds the very first Route component. The path is currently pointing towards the Home component which has the following UI logic.

function Home() {
   return (
       
           # Home Component

       
   )
}

Now, visit the URL on port 3000 and you will see the Home component being rendered right now.

This is a bare minimum example. Now let us add another route with the same props like the Home. Call this route About with a similar rendering logic as Home.

function About() {
   return (
       
           # About Component

       
   )
}

Now add this functional component as the second route, below the Home route. Also, add both routes inside a div element. A router component can hold a single child element and adding a div solves this problem and allows the router component to have as many children as we want.

function App() {
   return (
       
           
               
               
           
       
   )
}

Try visiting the URL [http://localhost:3000/about](http://localhost:3000/about "http://localhost:3000/about"). You will notice that both the components are being rendered right now on the path /about.

The reason for this is that regular expression engine that React Router uses internally considers both the routes that are being started with a forward slash / equal. To solve this issue, we can use another essential prop on the Home route called exact.


   
       
       
   


This exact is also known as a qualifier which states that the path must match the exactly the / and nothing after it, such as /about. Now, if you visit the browser window at the URL [http://localhost:3000/about](http://localhost:3000/about "http://localhost:3000/about") you will notice that only the about component is getting rendered this time.

What is BrowserRouter?

Do you remember reading earlier about that *react-router-dom* is used only in case of web applications? Well, react-router-dom library holds two types of routers API for a React application to use. One is called BrowserRouter that you have seen in action in the previous section. The other one is called HashRouter.

A BrowserRouter will always listen to URLs like: [http://localhost:3000/about](http://localhost:3000/about "http://localhost:3000/about") whereas a HashRouter will have [http://localhost:3000/#/about](http://localhost:3000/#/about "http://localhost:3000/#/about"), as the name suggests, uses a hash # in between. So why did we use the *BrowserRouter*?

BrowserRouter is a popular choice among modern day web applications. The main reason behind is that it uses HTML5 History API to keep track of the router history of your React app. The HashRouter has a use case for legacy browsers where window.location.hash is still being used to keep a track of routes in a SPA.

DIY Exercise 👇

Here is a small task for you. Modify directory structure like below screenshot and separate the two functional components Home and about in their own component files such that, in future, if they grow with more JSX to render.

You can totally skip this if you want and move on to the next section. But performing this small task will benefit you to have an understanding of the above concepts.

The Link Component

To navigate between to web pages in HTML, there is an `````` anchor tag available. However, using this traditional approach will lead to a browser refresh. In order to overcome this, React Router API offers a Link component that can be used to navigate to a particular URL or a component.

Let us try to create a navigation menu with this new knowledge. Import Link from react-router-dom in App.js file. Here is the modified snippet of App component.

// App.js

import React from "react"
import { BrowserRouter as Router, Route, Link } from "react-router-dom"

import Home from "./components/Home"
import About from "./components/About"

function App() {
   return (
       
           
               
                   
                       Home
                   

                   
                       About
                   
               
               
               
           
       
   )
}

export default App

In the above snippet, notice that all the Links are being added before all the Route components. The styling attributes inside style are optional for now. Start the development server and visit the browser window and you will notice a navigation menu pops up at the top. Try clicking links to navigate between different components.

Wherever a Link is rendered in a React project, an anchor `````` will be rendered in the application’s HTML.

Active Links with NavLink

In React Router API, NavLink is the extended version of the Link component. You can say that is a special type of the Link that can style itself as to represent the active state when matches the current route.

To demonstrate this, first, let us replace all the Link tags with NavLink in App.js file.

// App.js
import React from "react"
import { BrowserRouter as Router, Route, NavLink } from "react-router-dom"

import Home from "./components/Home"
import About from "./components/About"

function App() {
   return (
       
           
               
                   
                       Home
                   

                   
                       About
                   
               
               
               
           
       
   )
}

export default App

At this point, each NavLink link is going to behave like an ordinary Link component which means there is no change so far. To make a link active, add an activeClassName prop to that. Such as below.



To set up the corresponding CSS for this to work, open App.css file and add the below.

a {
   padding: 10px;
}

a,
a:visited {
   color: blue;
}

a.active {
   color: red;
}

Do not forget to import this file inside App.js. Also, modify the about route to have an activeClassName.

import "./App.css"

// ...

return (
 {/* */}
 
     
         Home
     

     
         About
     
 

 {/* */}
)

Go back to the browser, open develop tools like below and you will notice, at first, the Home route has a class name active.

Try navigating to the About route and see what happens.

On navigating to About route did you notice that the active class name is also added to the corresponding route? However, the Home route still has the active class even though the URL matches the /about. Why?

The way NavLink works is almost similar to Route component in React Router API. To make sure that only one route has the class active state, try modifying the home route in the navigation menu, as below.

//App.js


   Home


You will get the desired output this time.

Adding Parameters to the Routes

In this section, you will learn how to create and manage dynamic routes based on a query parameter such as :id. We start by creating a static array in App.js file that will serve as the mock data.

The idea is to demonstrate a route as /posts which displays all the posts that are coming from the array. However, each post in the array will be having an id or a unique identifier. Using that unique identifier, you will be approaching the concept of dynamic content rendering by writing the logic for URLs such as /posts/:id where :id will be represented by the specific id of a post.

To start, let us add a bunch of mock posts in the state inside a new component file called components/posts.js.

// Posts.js
import React from "react"
import "../App.css"

class Posts extends React.Component {
   state = {
       posts: [
           { id: 1, title: "Hello Blog World!" },
           { id: 2, title: "My second post" },
           { id: 3, title: "What is React Router?" }
       ]
   }

   render() {
       return (
           
               # Posts List

           
       )
   }
}

export default Posts

The corresponding styles to the above are added in App.css file for brevity.

.posts ul {
   list-style: none;
   margin: 0;
   margin-bottom: 20px;
   padding: 0;
}

.posts ul li {
   padding: 10px;
}

.posts a {
   text-decoration: none;
}

Now, import the newly created component inside App.js where other routes already exist.

//App.js
// ...
import Posts from "./components/Posts"

function App() {
   return (
       
           
               
                   
                       Home
                   
                   
                       About
                   
                   
                       Posts
                   
               
               
               
               
           
       
   )
}

export default App

The existing navigation menu has a new route and its called Posts.

Open Posts.js to render the list of Posts and display them as a list whenever the current location in the web browser matches /posts.

import React from "react"
import { Link, Route } from "react-router-dom"
import "../App.css"

function Child({ match }) {
   return (
       
           ### ID: {match.params.id}

       
   )
}

class Posts extends React.Component {
   state = {
       posts: [
           {
               id: 1,
               title: "Hello Blog World!"
           },
           {
               id: 2,
               title: "My second post"
           },
           {
               id: 3,
               title: "What is React Router?"
           }
        ]
   }

   render() {
       const { posts } = this.state
       return (
           
               # Posts List

               
                   {posts.map(post => (
                       
                           {post.title}
                       
                   ))}
               
               
           
       )
   }
}

export default Posts

Also, the Child component reads anything coming from the URL parameters, such as, in the above case, the id of each post. A match object contains information about how a `````` matched the URL, thus, in our case, the id of each post.

Connecting Crowdbotics support to Your Github Repo

Once everything is working, now let us add git version to this React project and then, further add the support for Crowdbotics app building platform. Open a terminal window and execute:

git init

# add all files
git add .

# commit
git commit -m "react-router-v4-demo"

Once all the files are committed, add this repository to your Github account. Crowdbotics app building platform now gives you an option to connect a Github repository directly using GitHub OAuth integration ( which means you need to have a Crowdbotics account or login into one using your Github account).

More and in-detail information about this process can be found here.

Conclusion

Hopefully, by now, you are familiar with the basic concepts of how React Router library works. It is a powerful library that helps you build better React apps. If you want to learn more about React Router visit its official documentation here.

You can find the complete for the tutorial at this Github repo.

JavaScript developers should you be using Web Workers?

JavaScript developers should you be using Web Workers?

Do you think JavaScript developers should be making more use of Web Workers to shift execution off of the main thread?

Originally published by David Gilbertson at https://medium.com

So, Web Workers. Those wonderful little critters that allow us to execute JavaScript off the main thread.

Also known as “no, you’re thinking of Service Workers”.

Photo by Caleb Jones on Unsplash

Before I get into the meat of the article, please sit for a lesson in how computers work:

Understood? Good.

For the red/green colourblind, let me explain. While a CPU is doing one thing, it can’t be doing another thing, which means you can’t sort a big array while a user scrolls the screen.

This is bad, if you have a big array and users with fingers.

Enter, Web Workers. These split open the atomic concept of a ‘CPU’ and allow us to think in terms of threads. We can use one thread to handle user-facing work like touch events and rendering the UI, and different threads to carry out all other work.

Check that out, the main thread is green the whole way through, ready to receive and respond to the gentle caress of a user.

You’re excited (I can tell), if we only have UI code on the main thread and all other code can go in a worker, things are going to be amazing (said the way Oprah would say it).

But cool your jets for just a moment, because websites are mostly about the UI — it’s why we have screens. And a lot of a user’s interactions with your site will be tapping on the screen, waiting for a response, reading, tapping, looking, reading, and so on.

So we can’t just say “here’s some JS that takes 20ms to run, chuck it on a thread”, we must think about where that execution time exists in the user’s world of tap, read, look, read, tap…

I like to boil this down to one specific question:

Is the user waiting anyway?

Imagine we have created some sort of git-repository-hosting website that shows all sorts of things about a repository. We have a cool feature called ‘issues’. A user can even click an ‘issues’ tab in our website to see a list of all issues relating to the repository. Groundbreaking!

When our users click this issues tab, the site is going to fetch the issue data, process it in some way — perhaps sort, or format dates, or work out which icon to show — then render the UI.

Inside the user’s computer, that’ll look exactly like this.

Look at that processing stage, locking up the main thread even though it has nothing to do with the UI! That’s terrible, in theory.

But think about what the human is actually doing at this point. They’re waiting for the common trio of network/process/render; just sittin’ around with less to do than the Bolivian Navy.

Because we care about our users, we show a loading indicator to let them know we’ve received their request and are working on it — putting the human in a ‘waiting’ state. Let’s add that to the diagram.

Now that we have a human in the picture, we can mix in a Web Worker and think about the impact it will have on their life:

Hmmm.

First thing to note is that we’re not doing anything in parallel. We need the data from the network before we process it, and we need to process the data before we can render the UI. The elapsed time doesn’t change.

(BTW, the time involved in moving data to a Web Worker and back is negligible: 1ms per 100 KB is a decent rule of thumb.)

So we can move work off the main thread and have a page that is responsive during that time, but to what end? If our user is sitting there looking at a spinner for 600ms, have we enriched their experience by having a responsive screen for the middle third?

No.

I’ve fudged these diagrams a little bit to make them the gorgeous specimens of graphic design that they are, but they’re not really to scale.

When responding to a user request, you’ll find that the network and DOM-manipulating part of any given task take much, much longer than the pure-JS data processing part.

I saw an article recently making the case that updating a Redux store was a good candidate for Web Workers because it’s not UI work (and non-UI work doesn’t belong on the main thread).

Chucking the data processing over to a worker thread sounds sensible, but the idea struck me as a little, umm, academic.

First, let’s split instances of ‘updating a store’ into two categories:

  1. Updating a store in response to a user interaction, then updating the UI in response to the data change
  2. Not that first one

If the first scenario, a user taps a button on the screen — perhaps to change the sort order of a list. The store updates, and this results in a re-rendering of the DOM (since that’s the point of a store).

Let me just delete one thing from the previous diagram:

In my experience, it is rare that the store-updating step goes beyond a few dozen milliseconds, and is generally followed by ten times that in DOM updating, layout, and paint. If I’ve got a site that’s taking longer than this, I’d be asking questions about why I have so much data in the browser and so much DOM, rather than on which thread I should do my processing.

So the question we’re faced with is the same one from above: the user tapped something on the screen, we’re going to work on that request for hopefully less than a second, why would we want to make the screen responsive during that time?

OK what about the second scenario, where a store update isn’t in response to a user interaction? Performing an auto-save, for example — there’s nothing more annoying than an app becoming unresponsive doing something you didn’t ask it to do.

Actually there’s heaps of things more annoying than that. Teens, for example.

Anyhoo, if you’re doing an auto-save and taking 100ms to process data client-side before sending it off to a server, then you should absolutely use a Web Worker.

In fact, any ‘background’ task that the user hasn’t asked for, or isn’t waiting for, is a good candidate for moving to a Web Worker.

The matter of value

Complexity is expensive, and implementing Web Workers ain’t cheap.

If you’re using a bundler — and you are — you’ll have a lot of reading to do, and probably npm packages to install. If you’ve got a create-react-app app, prepare to eject (and put aside two days twice a year to update 30 different packages when the next version of Babel/Redux/React/ESLint comes out).

Also, if you want to share anything fancier than plain data between a worker and the main thread you’ve got some more reading to do (comlink is your friend).

What I’m getting at is this: if the benefit is real, but minimal, then you’ve gotta ask if there’s something else you could spend a day or two on with a greater benefit to your users.

This thinking is true of everything, of course, but I’ve found that Web Workers have a particularly poor benefit-to-effort ratio.

Hey David, why you hate Web Workers so bad?

Good question.

This is a doweling jig:

I own a doweling jig. I love my doweling jig. If I need to drill a hole into the end of a piece of wood and ensure that it’s perfectly perpendicular to the surface, I use my doweling jig.

But I don’t use it to eat breakfast. For that I use a spoon.

Four years ago I was working on some fancy animations. They looked slick on a fast device, but janky on a slow one. So I wrote fireball-js, which executes a rudimentary performance benchmark on the user’s device and returns a score, allowing me to run my animations only on devices that would render them smoothly.

Where’s the best spot to run some CPU intensive code that the user didn’t request? On a different thread, of course. A Web Worker was the correct tool for the job.

Fast forward to 2019 and you’ll find me writing a routing algorithm for a mapping application. This requires parsing a big fat GeoJSON map into a collection of nodes and edges, to be used when a user asks for directions. The processing isn’t in response to a user request and the user isn’t waiting on it. And so, a Web Worker is the correct tool for the job.

It was only when doing this that it dawned on me: in the intervening quartet of years, I have seen exactly zero other instances where Web Workers would have improved the user experience.

Contrast this with a recent resurgence in Web Worker wonderment, and combine that contrast with the fact that I couldn’t think of anything else to write about, then concatenate that combined contrast with my contrarian character and you’ve got yourself a blog post telling you that maybe Web Workers are a teeny-tiny bit overhyped.

Thanks for reading

If you liked this post, share it with all of your programming buddies!

Follow us on Facebook | Twitter

Further reading

An Introduction to Web Workers

JavaScript Web Workers: A Beginner’s Guide

Using Web Workers to Real-time Processing

How to use Web Workers in Angular app

Using Web Workers with Angular CLI


Why ReactJS is better for Web Application Development?

Why ReactJS is better for Web Application Development?

Web Application Development is the point of contact for a business in today's digital era. It is important to choose the right platform for Web Application Development to build a high end Web

Web Application Development is essential for a business in today’s digital era. Finding the right platform for Web Application Development is important for building an effective Web Application that can enhance the overall customer engagement. Here’s what makes ReactJS a better option for building your next Web Application.