Before moving toward implementing and applying a dynamic web page using React hydration, let’s have a brief intro about React, ReactDOM, its functions, server-side rendering (SSR), and Hydration.
React is an open-source JavaScript library that we use to create efficient web applications. On the other hand, ReactDOM has render()
and hydrate()
, which help render the web application. We’ll see these functions in action later in this Answer. Moreover, ReactDOM allows easy management of the DOM components.
SSR is a technique used in React to initialize the web page’s HTML on the server side, not at the user’s browser. The server-generated HTML and React components are sent to the browser. Hydration is used to convert this server-rendered content to interactive user-side web applications.
As briefed above, this Answer will discuss the dynamic capability of web applications using React hydration.
To understand the hydration process, we must clearly understand what server-side rendering is. In SSR, when a user requests a web page, the server prepares the HTML of the requested web pages after fetching the user’s data. After preparing the web page content specific to the user, the server sends the web page over to the user’s browser. The sent content is static server-generated content. The HTML is then displayed on the user’s browser. Here, the ReactDOM server performs the server-side rendering process. The creating, fetching from the database, and loading takes a few milliseconds.
It is important to notice that our current content is static content presented as HTML. To add dynamic features to the content or to change the content, we use hydration. Hydration improves the interactivity of the user’s web application.
ReactDOM.hydrate
is an important step in the server-side rendering process. It is used to fill in the gap between the static HTML markup and the dynamic behavior of the React components. The steps involved in the hydration process are:
Initial static HTML markup: The server sends server-generated static markup using the ReactDOM server to the user browser.
JavaScript bundle loading: The ReactDOM server loads the JavaScript on the user’s browser to render React components and their associated behavior.
Hydration: React starts the hydration process after the static rendering. Instead of re-rendering the whole process, React uses the sent HTML markup and attaches event listeners to the static elements representing React components.
Reconciliation: React uses the comparison mechanism to compare the HTML markup and the virtual DOM generated during the rendering process. The differences are identified between the two.
Attaching event listeners: React then attaches event listeners to the components. This helps add interactivity to the React web application.
Reusing existing DOM: React uses the existing DOM, unlike render()
, which creates the HTML from scratch. React tries to preserve the interactions that occurred before loading the JavaScript bundle.
The process is faster as it allows using HTML already present in the browser. It preserves user interactions, allows the identification of changes in the initial DOM, and improves the user’s experience by leveraging the existing DOM structure.
Let’s examine a code example for the Hydration process and how it creates a dynamic web page.
import React from "react"; import {useState} from "react"; export const FrequencyCalc = () => { const [freq, setFreq] = useState(0); return( <div> <button onClick={()=> setFreq(freq+1)}>Frequency updater</button> <h1>Frequency: {freq}</h1> </div> )}
Here, index.html
serves as a custom server-generated markup HTML. In index.js
, the initial script calls the root
from index.html
and then hydrates the HTML markup using the App()
function. The hydrate uses the custom HTML in index.html
and App
script to change the server-generated HTML.
In the app.js
file:
Line 1: We import the React library, which is necessary to write React components.
Line 2: We import the FrequencyCalc
component from the freqCalc.js
file.
Lines 4–10: This function is a React functional component. It returns JSX that renders a div
containing a heading and the FrequencyCalc
component. The App
function is the default export of this module, making it available for import in other files.
The index.html
file:
We use this HTML file to contain a single <div>
element with the ID root
. This is where we will mount our React application.
In the index.js
file:
Lines 1–3: We import the React library, the hydrateRoot
function from the react-dom/client
package. This function is used to hydrate a server-rendered React application. And the App
component from the App.js
file.
Lines 5–8: We call the hydrateRoot
function with two arguments:
The first argument is the DOM element with the ID root
.
The second argument is the App
component, which will be rendered into the root
element.
In the freqCalc.js
file:
Lines 1 and 2: We import the React library, and the useState
hook from React, which is used to manage state in functional components.
Lines 4–11: We define and export a functional component called FrequencyCalc
where we use the useState
hook to create a state variable freq
and a function setFreq
to update it. We have the initial state to 0
.
The FrequencyCalc
component returns a JSX expression. The top-level element is a <div>
. And, inside the <div>
, there's a <button>
element. When we click on the button, the setFreq
function is called to increment the freq
state by 1. You can see this by clicking on the "Run" button on the code widget.
In summary, after the hydration process, React handles the dynamic data by using props and state. The components exchange data using API calls. React rerenders the components in which changes have occurred. It updates the changes faster because of its reconciliation and virtual DOM mechanisms.
Take your React development skills to the next level with Next.js - The Ultimate Way to Build React Apps. Learn how to optimize your app’s performance, improve SEO, and create a fully functional Giphy search app.
Free Resources