Reputation: 288
I try to get an item from my localstorage with next.js without rerender my page.
I use this code:
import { ThemeProvider } from "@material-ui/core";
import { FC, useEffect, useState } from "react";
import { useStore } from "../hooks/ContextStore";
import { darkTheme, theme } from "../theme/theme";
import Navbar from "./navbar/Navbar";
const Layout: FC = ({ children }) => {
const [darkMode, setDarkMode] = useState(false);
const store = useStore();
useEffect(() => {
setDarkMode(JSON.parse(window.localStorage.getItem("dark-mode")));
}, [store.darkMode]);
console.log("did render");
return (
<ThemeProvider theme={darkMode ? darkTheme : theme}>
<Navbar />
{children}
</ThemeProvider>
);
};
export default Layout;
Because my useEffect update my state it is rendering the page twice when I turn on or off the dark mode state.
Is there a way to prevent it from rerender that much and accessing the localstorage?
Upvotes: 1
Views: 642
Reputation: 574
From the looks of it, because your state value is alway going to be from the localstorage, then you don't need to store it in the state. You can just do something like so:
const isClient = typeof window !== undefined;
const Layout: FC = ({ children }) => {
const store = useStore();
const darkMode = isClient && JSON.parse(window.localStorage.getItem("dark-mode"));
return (
<ThemeProvider theme={darkMode ? darkTheme : theme}>
<Navbar />
{children}
</ThemeProvider>
);
}
export default Layout;
If you really want to store in the state, then you should update the dependency array in useEffect to look for updates in the localstorage value, not the state because you'll be updating the state.
const storageDarkMode = JSON.parse(window.localStorage.getItem("dark-mode"));
useEffect(() => {
setState(storageDarkMode);
}, [storageDarkMode])
Upvotes: 1