I have a sidebar menu that has been successfully hidden and shown. When the sidebar menu is hidden and I refresh the page or browser, the hidden sidebar menu will return to its original appearance
How can I avoid this? I want the sidebar open instead on desktop view. It is a dashboard.
This is the ContextProvider.js
import { useState, createContext, useContext, useEffect } from "react";
const StateContext = createContext()
const initialState = {
cart: false,
notification: false,
searchBar: false,
}
export const ContextProvider = ({ children }) => {
const [activeMenu, setActiveMenu] = useState(true)
const [isClicked, setIsClicked] = useState(initialState)
const [screenSize, setScreenSize] = useState(undefined)
const [currentColor, setCurrentColor] = useState('#bf9a8e')
const [currentMode, setCurrentMode] = useState('Light')
const [isOpen, setIsOpen] = useState(false)
const [currentIndex, setCurrentIndex] = useState(0)
const setMode = (e) => {
setCurrentMode(e.target.value);
localStorage.setItem('themeMode', e.target.value);
};
const setColor = (color) => {
setCurrentColor(color);
localStorage.setItem('colorMode', color);
};
const handleClick = (clicked) => {
setIsClicked({...initialState, [clicked]: true})
}
const slideLeft = () => {
let slider = document.getElementById('slider-2')
slider.scrollLeft = slider.scrollLeft - 500
}
const slideRight = () => {
let slider = document.getElementById('slider-2')
slider.scrollLeft = slider.scrollLeft + 500
}
return (
<StateContext.Provider value={{
activeMenu,
setActiveMenu,
isClicked,
setIsClicked,
handleClick,
screenSize,
setScreenSize, currentColor,
currentMode,
setColor,
setMode,
isOpen,
setIsOpen,
slideLeft,
slideRight,
currentIndex,
setCurrentIndex,
}}>
{children}
</StateContext.Provider>
)
}
export const useStateContext = () => useContext(StateContext)
I think I should place a useEffect hook to change the initial state but I am not sure if it can solve this issue. This is my sidebar component
function Sidebar() {
const { activeMenu, setActiveMenu, screenSize, currentColor } = useStateContext();
const handleCloseSideBar = () => {
if (activeMenu !== undefined && screenSize <= 900) {
setActiveMenu(false);
}
};
const activeLink = 'flex items-center gap-5 pl-4 pt-3 pb-2.5 text-gray-100 dark:text-white rounded-lg bg-slate-700 text-md m-2'
const normalLink = 'flex items-center gap-5 pl-4 pt-3 pb-2.5 rounded-lg text-md dark:text-gray-300 text-gray-500 dark:hover:text-gray-600 m-2 hover:bg-gray-200';
return (
<div className="mr-4 ml-4 mt-3 scrollbar-hide h-screen md:overflow-hidden overflow-auto md:hover:overflow-auto pb-10">
{/* LOGO SECTION */}
{activeMenu && (
<>
<div className="flex text-slate-700 dark:text-white justify-between">
<Link
to="/"
onClick={handleCloseSideBar}
className="flex text-xl font-extrabold items-center gap-3 ml-4 mt-4 tracking-tight"
>
<GiPlanetCore/>
<span>BaIlEyWoRld</span>
</Link>
<button
type="button"
onClick={() => setActiveMenu((prevActiveMenu) => !prevActiveMenu)}
className="text-2xl p-3 mt-4 block sm:hidden"
>
<MdClose />
</button>
</div>
<div className="mt-10">
{links.map((item) => (
<div key={item.title}>
<p className="text-gray-400 dark:text-gray-200 font-semibold uppercase m-4 mt-4">
{item.title}
</p>
{item.links.map((link) => (
<NavLink
to={`/${link.name}`}
key={link.name}
onClick={handleCloseSideBar}
className={({isActive}) =>
isActive ? activeLink : normalLink
}
style={({isActive}) => ({backgroundColor: isActive ? currentColor : ''})}
>
{link.icon}
<span>{link.name}</span>
</NavLink>
))}
</div>
))}
</div>
</>
)}
</div>
);
}
export default Sidebar
3
Answers
This is because you can’t keep a state when you refresh your page. A solution could be to use query params and add for example
?open=true
when your activeMenu change. So in that case you can get the previous state when the page is refreshed and set ittrue
by default.ex:
To maintain the state of the sidebar menu being hidden or shown even after a page refresh, you can utilize local storage to store the state information and retrieve it when the page reloads.
Add this in your Sidebar
You can update the useEffect hook in your ContextProvider.js file to store the state in localStorage whenever it changes and retrieve it when the component mounts.
"whenever the isOpen state changes, it will be stored in localStorage. And when the component mounts, it will check if there is a stored value and set the state accordingly"