Reputation: 356
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
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.
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