Overview
At some point in your journey as a developer, You must have likely heard of the term "hydration", but may not seem to understand how it works fully. In this article, I will be covering everything you need to know about hydration as a developer.
What is React hydration?
React Hydration is simply the process of adding event listeners to dom nodes and making an application fully interactive on the client side
In a Nextjs Application, when the client sends a request to the server, the server responds back with a pre-rendered html(server-generated markup) page. The pre-rendered page is then sent to the client side which populates the dom. After it is rendered on the client side, React takes over and adds event listeners to the server pre-rendered html(server-generated markup) populated on the client side bringing about interactivity.
Deeper detail of what happens during Request Time
During Request time, the following things listed below explain clearly what happens behind the scenes:
A preview of a non-interactive HTML is initially sent to the client from the server
React Server component payload: The React Server component which contains the data sent from the server to the client ensures that the client is in sync with the server bringing about the consistency of user interfaces.
Finally, the javascript instructions from the client side now hydrate the html page allowing it to be fully interactive.
Common Hydration Errors and how to resolve them
At some point, when you develop an application with nextjs, you might have come across this famous error.
This error can be very hard to debug and fix, especially when it occurs in a big application.
What exactly is a hydration error?
The hydration error is the error that stems from the mismatch of the server and client component's states and generated markup.
What causes it?
Just Like I explained earlier on hydration, In a Nextjs Application, React components are first rendered on the server before they are transformed into a pre-rendered html that is then sent to the client before the hydration process happens. However, during the process, if the javascript instructions executed on the client don't match the pre-rendered html that is sent from the server, hydration errors can occur.
There are several causes of hydration errors we face in our nextjs application, let's look at some of them as we proceed.
- Asynchronous rendering:
This involves trying to asynchronously render a simple component using getServerSideProps
and getInitialProps
. The getInitialProps plays a huge part in delaying the required data before it gets to the client side. if the client-side hydration process happens before the required data is loaded, hydration errors occur.
Data-Fetching: Nextjs uses React APIs to render the server components into a special data format, the format is fetched and sent to the client. If the data the client expects doesn't match with the one sent from the server, hydration errors occur.
- Third-Party Libraries
Nextjs as a react framework rely heavily on third-party libraries. These third-party libraries have their lifecycle rendering process which can conflict with nextjs rendering process leading to hydration errors
- Writing code that relies on the window object:
This is one of the major causes of hydration error that occurs in a nextjs application.
{user.status === "loggedIn" ? (
{/* condition when the user is logged in*/}
) : typeof window !== "undefined" && window.clientInformation.vendor ? (
{/* condition when */}
) : (
<p>
A user is logged in
</p>
)}
if you take a look at the code above, you will notice that it relies on a window object to execute a certain action. it is important to know that the window object in question is not available on the server enabling the pre-rendered html page not to match the client javascript code.
Best Practices
- Implement the UseEffect Logic on the client side: In the problem I shared above before this section, I showed you how the window object can be a cause of hydration error in a nextjs application. I also explained that in the server, the window object does not exist, which causes a mismatch of the server-generated markup and the client javascript functions needed to reconcile that same server-generated markup. So to resolve this issue, a useEffect is needed.
import { useEffect, useState } from 'react';
function MyComponent() {
const [isClientAvailable, setIsClientAvailable] = useState(false);
useEffect(() => {
if (typeof window !== 'undefined' && window.clientInformation.vendor) {
setIsClientAvailable(true);
}
}, []);
return (
<>
{user.status === "loggedIn" ? (
{/* condition when the user is logged in*/}
) : isClientAvaliable ? (
{/* condition when there is client ] */}
) : (
<p>
Oops no client
</p>
)}
</>
);
}
Disable pre-rendering for certain components: There are certain components that don't need to undergo server-side components, so disabling ssr will be a good option to avoid hydration errors.
Consistency in Fetching data: Ensure the use of Next.js hooks like getStaticProps and getServerSideProps during SSR to fetch data.
Conclusion
So now that you have fully understood hydration, its errors, the causes of those errors, and best practices to avoid them, you will be able to build highly scalable and powerful applications as a developer. Ensure to keep these best practices and guides in mind, and write good tests for your application so that you don't get fazed by hydration errors when debugging in your application. I hope I have been able to simplify everything related to hydration for you.
I'd love to connect with you on Twitter | LinkedIn | GitHub
See you in my next blog article. Happy Coding!!
Top comments (2)
It looks like you forgot to use isClientAvailable in the last example of the article.
Oh, it was an oversight, thanks for bringing it to my attention.