Reputation: 3149
I have an <Authenticated>
component that is used to render all of my authenticated routes. I want to prevent rendering the page until I have checked a token stored in sessionStorage
.
'use client';
export const Authenticated = ({ children }) => {
const token = typeof window !== 'undefined' ? sessionStorage.getItem('token') : null;
if (!token) {
return <></>;
}
return (
<main>{children}</main>
);
}
This works but I get this hydration error:
Uncaught Error: Hydration failed because the initial UI does not match what was rendered on the server.
Is there a better way to do this?
Upvotes: 0
Views: 80
Reputation: 1637
According to the Next.js docs hydration errors can be caused by:
Using checks like
typeof window !== 'undefined'
in your rendering logic
That is what you are doing here:
const token = typeof window !== 'undefined' ? sessionStorage.getItem('token') : null;
Instead wrap your session handling logic into your useEffect
hook. This will ensure that you only check for a token
when the page has fully loaded and that window
is available:
'use client';
import React, {useState, useEffect} from 'react';
export const Authenticated = ({ children }) => {
const [token, setToken] = useState('');
useEffect(() => {
setToken(window.sessionStorage.getItem('token'))
}, [])
return (
{token ? <main>{children}</main> : null}
);
}
A few things to note about this approach:
We are using state to store the token. This is because token
will be falsy before useEffect
runs. This lets us update the state and re-render the UI once the token is retrieved
Building off of the last point we are using a ternary operator to determine whether to render something or not. The reason the previous approach might not have worked(even if you fixed the hydration error) is because of this logical error, your code says:
{children}
The problem is the first condition will always be true
right away then maybe false. However, currently you would just return before you met the true condition. But when using if/else logic inside on single return
you can fix this issue
Upvotes: 1