Search code examples
javascriptreactjsreact-hooksmedia-queries

React Hooks + Media Query page refresh issue


I created a responsive sidebar, the logic is implemented as follows, when the screen reaches below 765 pixels the sidebar is automatically hidden, but the problem is that when I refresh the page which is below 765 pixels the sidebar is displayed it looks like this

enter image description here

My code looks like this

function SideBar(props) {
    const {someValue} = useContext(SideBarContext);
    const {SideBarValue, SideBarWallpaperValue} = React.useContext(CounterContext);

    const [SideBarThemeValue] = SideBarValue;
    const [SideBarBackgroundValue] = SideBarWallpaperValue;

    const [sideBarOpen, setSideBarOpen] = useState(true);
    const [SideBarButtonContainer, setSideBarButtonContainer] = useState(false);

    useEffect(() => {
        window.addEventListener("resize", resize);
    })

    const resize = () => {
        if(window.innerWidth < 765) {
            setSideBarOpen(false)
            setSideBarButtonContainer(true)
        } else {
            setSideBarOpen(true)
            setSideBarButtonContainer(false)
        }
    }
    

    const showSideBar = () => {
        setSideBarOpen(!sideBarOpen)
    }

    return (
        <>
            {
                SideBarButtonContainer ? <div className={"showSideBarButtonContainer"}>
                    <img className={"showSideBarButton"} onClick={() => showSideBar()} src={SideBarMenuIcon} alt={"Open"} />
                </div> : null
            }
            <Menu isOpen={sideBarOpen}>
                
            </Menu>
        </>
    );
}

I assume that when I refresh the page the sideBarOpen value becomes true, although I did a check inside the resize method and notice when I start to shrink the screen the sidebar disappears it looks like this

enter image description here


Solution

  • The default state of your sidebar is open, however you must calculate the initial state based on the width. Also you must only initialise the listener on window resize on initial render.

    const [sideBarOpen, setSideBarOpen] = useState(() => window.innerWidth > 765);
    const [SideBarButtonContainer, setSideBarButtonContainer] = useState(() => window.innerWidth < 765);
    
    useEffect(() => {
        window.addEventListener("resize", resize);
    }, []); // Only initialize listener on initial render
    
    const resize = () => {
        if(window.innerWidth < 765) {
            setSideBarOpen(false)
            setSideBarButtonContainer(true)
        } else {
            setSideBarOpen(true)
            setSideBarButtonContainer(false)
        }
    }