Skip to content

Instantly share code, notes, and snippets.

@christiannwamba
Created May 26, 2018 12:09
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save christiannwamba/a509962823b2ad51a9e07e7898cc57b6 to your computer and use it in GitHub Desktop.
Save christiannwamba/a509962823b2ad51a9e07e7898cc57b6 to your computer and use it in GitHub Desktop.

Setup React Hotloader In 10 Minutes

Introduction

Several years ago, it was becoming tiring (and annoying in the case where the changes do not render as expected) to refresh the browser to see the most recent updates on a web project. In a bid to solve this problem, developers created several plugins and tools that can cause the DOM to re-render on each save without even doing a full-reload. This is called hot-reloading and it works by replacing a module of the application during run-time with an updated one, so that it’s available for instant use.

This leads us to talk about Hot Module Replacement (HMR).

HMR as the name implies, can replace modules without restarting the server and can easily be enabled with different bundlers.

On Webpack’s website, it is stated that:

Hot Module Replacement (HMR) exchanges, adds, or removes modules while an application is running, without a full reload. This can significantly speed up development in a few ways.

HMR solves the problem of hot-reloading quite alright, makes it easier to tweak styling (almost comparable to changing styles in the browser's debugger) and generally speeds up the development process. But what happens when we live-reload in a component based framework like React that keeps track of its states? We lose the state.

The reason we lose the state can be understood by the difference between hot-reload and live-reload:

A hot reload to an app will only refresh the files that were changed without losing the application’s state.

A live reload to an app will restart the entire app, and load cause it to lose its state.

The primary aim of this tutorial is to demonstrate how we can quickly setup react-hot-loader for our React application so that its components can be live-reloaded without a loss in state.

The resulting code for this article is available here on GitHub.

Prerequisites

  1. Please ensure that you have Node and npm installed before starting the tutorial
  2. Very basic knowledge of React is assumed and a general understanding of JavaScript would be helpful
  3. We will be using the create-react-app tool to create the React Application

If you don’t already have the create-react-app tool on your computer, you can install it with this command:

npm install -g create-react-app

Setup the development environment

Let’s spin up a new instance of a create-react-app project and navigate into the newly created directory with these commands:

create-react-app react-hot-loader-demo
cd react-hot-loader-demo

We can run the application using this command:

npm start

This command starts the web server that points to the address localhost://3000. We will visit this address on our browser and keep the tab open because throughout this tutorial, we will be monitoring the updates and behavior of the application in the browser.

When we create a new project using the create-react-app, the Hot Module Replacement (HRM) plugin is enabled by default in the Webpack configuration file, though we can’t see this file because create-react-app configures our application for us and hides the configuration files.

Checking the Hot-Reload behaviour

We can see the HRM’s hot-reloading in action by adding a basic style to the index.css file that’s included out of the box. We’ll add a property value pair — background: lightblue — to the body style:

https://gist.github.com/267068db33787aadd8f82c0ea4927e45

On saving this, the application updates without the browser tab refreshing:

This behavior is possible because the HRM is able to replace a module of code in the application during run-time.

Checking The Hot-reload Behavior With A JavaScript File

Now let’s see what happens when we edit the content in the App.js file, we can do something as basic as replacing the "To get started, edit src/App.js and save to reload.” with “This is a tutorial to setup React Hotloader.”

https://gist.github.com/eeaa13bbd961659955a580a0a46b9b92

This time, it can be observed that the application does a live-reload and the entire page refreshes so that the change can be implemented. The reason this happens is because the HMR is unable to decide how to handle the update to this JavaScript file. Naturally, hot-reloads are possible when the HMR receives an update at run-time and confirms that the concerned module knows how to update itself. Where the module knows how to update itself, the HMR then goes up the import/require chain, searching for a parent module that can accept the update. Let’s tweak our application a bit so that the HMR knows how to handle JavaScript files for hot-reloads.

In the index.js file (which is the entry point of our application) we will add this line of code:

https://gist.github.com/106af7867146f9fa30f9e45bfc630cbd

This code will make it possible for the updates to our React components to do hot-reloads because the parent module (index.js) now knows how to accept and process the run-time updates. Now lets make a new update to the App.js file by replacing the line that says This is a tutorial to setup React Hotloader.. with This update will not cause a refresh to the browser tab:

https://gist.github.com/7eefe92460811913671ce24945d2aaf0

The resulting page:

This update is handled as a hot-reload and didn’t cause the browser to refresh!

Checking The Hot-reload Behavior With a State Variable

Everything we have done has been awesome so far. Let’s see what happens when we include a basic state variable to the application, we can also add a function to make it increment on click events:

https://gist.github.com/eb6c1abe34a390c8bc8484197f0eca36

When we save this code and it hot-reloads, we can click on the buttons 12 times to increment it:

It works just as we wanted it to, however, what happens if we make an edit to the JavaScript file and save it now? It should do a hot-reload just as before and also preserve the value of the state variable, right? Let’s see about that. Let's replace the line The current value of number is *{this.*``state``*.*``number``*}* with Will the state be preserved? The value is *{this.*``state``*.*``number``*}*:

https://gist.github.com/b9f5b064d6ad1889add169a01974fd5c

On saving it, we get this screen:

What just happened? Wasn’t our number equals to twelve a few seconds ago? Where did that value go? That’s right, during the hot-reload, the component unmounted and the constructor had to re-run when the component was mounted again. We lose state data even with the hot-reload features HMR gives to us.

We can handle this issue using the React Hotloader plugin and doing some configurations.

Setting Up React Hotloader

First of all, we want to eject our application so we can customize its configuration:

npm run eject

Running npm run eject copies all the configuration files and the transitive dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. Commands like npm start and npm run build will still work, but they will point to the copied scripts so you can tweak them.

Doing this is also permanent

Next, we pull in React Hotloader which is a plugin that allows React components to be live reloaded without the loss of state. It works with Webpack and other bundlers that support both Hot Module Replacement (HMR) and Babel plugins.

npm install --save react-hot-loader

Linux users might need to prefix this command with sudo for premission reasons

When this is done installing, we want to navigate into the config/webpack.config.dev.js that is now available to us, add this line — plugins``**:** ['react-hot-loader/babel'] — to the Babel loader configuration. This is what it should resemble:

https://gist.github.com/050a04c2389cdccbb1ed898b1590ace7

The next thing we want do is open our application’s entry point again and wrap the app’s top-level component inside of an <AppContainer>. We have to import import the <AppContainer> from react-hot-loader first:

https://gist.github.com/484c8fff46466088a73dbdceef28e19b

Let’s modify the module.hot section so that we can also render the <AppContainer> within it:

https://gist.github.com/e7ad1094d1dbec28e012028b3f874c21

This modification tells the <AppContainer> to process the module reloading and handle any errors that might be created during run-time.

The would be disabled in the production environment

Lastly, we need to require the react-hot-loader patch into our entry point file:

https://gist.github.com/7685b2dc5f6ae13cc209ca8c413f3fdd

We require this because it’s responsible for patching the code at low-level processing.

Testing React Hotloader

Let’s test our application to see if the state would be preserved on updates now, we can accomplish this by saving the updates we just made and running the application:

npm start

We can click on the button to increase the number variable to a number like 36:

Now, lets make a quick edit to the code and save it to see if the state persists:

https://gist.github.com/4d9fd2ec015a5b76978b144bbdca65f7

This update causes the browser window to update to this:

Awesome! The state persisted despite the change we made to the document, this means that our react-hot-loader works perfectly and handles module reloading for us.

Conclusion

In this tutorial, we have gone from understanding why hot-loading is important to specify the difference between a hot-reload and a live reload. We have also seen how to quickly and easily setup a React application for hot-reload using the react-hot-loader plugin so that the value of all states present in the application can be persisted regardless of the updates made. The final code of this article is available here on GitHub.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment