EliyaMelamed
EliyaMelamed

Reputation: 356

Next js how to fetch localStorage data before client side rendering

I am using react + next.js in my client side and I am getting this weird warning, which I've failed to fix over the previous 3 days.

I assume the Warning arise in because the isUserAuthenticated value is saved on the localStorage.

and localStorage is only available on the client side, and therefore the value is diffrent from the initial data rendered on the server.

after searching on google I read a few post which suggested using componentDidMount() to in order to load the localStorage values before the the client side in rendred.

unfortunelty I've failed to implement this idea, threfore I am asking for help, can someone help me to to solve this problem? thanks in advance

The warning:

react-dom.development.js:67 Warning: Text content did not match. 
Server: "false" Client: "true"
    at div
    at ul
    at div
    at nav
    at Navbar

Navbar.js

const Navbar = () => {
    const { isUserAuthenticated,  } = useSelector((state) => state.authReducer);

    return (
        <nav data-testid='navbar'>
            <div>
                <>{isUserAuthenticated ? <div>true</div> : <div>false</div>}</>
            </div>
        </nav>
    );
};

export default Navbar;

the solution

// TODO recipes crud to navbar
// test author and guest links

import {  useSelector } from 'react-redux';

import React from 'react';

const Navbar = () => {
    const [isUserAuthenticated, setIsUserAuthenticated] = useState();
    useEffect(() => {
        setIsUserAuthenticated(store.getState().authReducer.isUserAuthenticated);
    }, []);

    return (
        <nav data-testid='navbar'>
            <div>
                <>{isUserAuthenticated ? <div>true</div> : <div>false</div>}</>
            </div>
        </nav>
    );
};

export default Navbar;

Upvotes: 0

Views: 2340

Answers (1)

felixmosh
felixmosh

Reputation: 35493

This error happens when your server returns a different html structure than your client side, this will force React to re-render the entire App instead just attach event listeners (which is much faster).

From the error, looks like your isUserAuthenticated & loggedUserData have different values at client side & server side, Print them, if this is the situation, check the reason for this.

Edit

As you've mentioned, localStorage available only at client side, this means that your code most support it. At the serverSide (there is no localStorage) your isUserAuthenticated should return false. At the client side, you should "continue" the server state (which means that you don't load the value from localStorage firstly), then when the app is mounted, load the value.

if you are using classes, use the componentDidMount (which runs only at client side) in order to update the value of isUserAuthenticated.

if you are using hooks, use the useEffect hook (which runs only at client side) in order to update the value of isUserAuthenticated.

Upvotes: 3

Related Questions