I have been trying to solve this problem for a couple days but can't seem to get it to work.
First, I have a custom hook to get if the client is viewing in mobile or desktop format.
that looks like this:
import { useState, useEffect } from "react";
function getWindowDimensions() {
if (typeof window !== "undefined") {
const { innerWidth: width, innerHeight: height } = window;
console.log("defined");
console.log(width < 768);
return width < 768 ? true : false;
}
console.log("undefined");
return true;
}
export default function useWindowDimensions() {
const [windowDimensions, setWindowDimensions] = useState(
getWindowDimensions()
);
function handleResize() {
setWindowDimensions(getWindowDimensions());
}
useEffect(() => {
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, []);
return windowDimensions;
}
Now I am trying to use this in order to switch between a footer or a header style interaction on my website:
import useWindowDimensions from "hooks/useWindowDimensions";
import React, { useEffect } from "react";
import Footer from "./Footer";
import Header from "./Header";
export default function Shim(props) {
const isMobile = useWindowDimensions();
return (
<div>
{!isMobile && <Header {...props} />}
{isMobile && <Footer {...props} />}
</div>
);
}
I expected this to work perfectly, however it looks as if the the initial value is getting set when typeof window === "undefined", so, the mobile view is rendered in desktop size (if I resize the window after the site is loaded, it works as expected.) Would anyone be willing to lend me a hand as to how to get this to work appropriately?
Thank you!
I solve same problem with this context api hook.
import React, { createContext, useContext, useEffect, useState } from 'react';
export const SizeContext = createContext();
const SizeContextProvider = ({ children }) => {
const [width, setWidth] = useState(window.innerWidth);
const [isMobile, setIsMobile] = useState(true);
const [isDesktop, setIsDesktop] = useState(true);
function debounce(fn, ms) {
let timer;
return () => {
clearTimeout(timer);
timer = setTimeout(() => {
timer = null;
fn.apply(this, arguments);
}, ms);
};
}
useEffect(() => {
const debouncedHandleResize = debounce(() => {
setWidth(window.innerWidth);
}, 0);
window.addEventListener('resize', debouncedHandleResize);
return () => {
window.removeEventListener('resize', debouncedHandleResize);
};
});
useEffect(() => {
if (width <= 575) {
setIsMobile(true);
setIsDesktop(false);
} else if (width >= 576 && width < 767) {
setIsMobile(true);
setIsDesktop(false);
} else if (width >= 768 && width < 991) {
setIsMobile(false);
setIsDesktop(true);
} else if (width >= 992 && width < 1199) {
setIsMobile(false);
setIsDesktop(true);
} else {
setIsMobile(false);
setIsDesktop(true);
}
}, [width]);
return (
<SizeContext.Provider value={{ width, isDesktop, isMobile }}>
{children}
</SizeContext.Provider>
);
};
export const useSizeContext = () => useContext(SizeContext);
export default SizeContextProvider;
import context api use any component.
const App = () => {
return (
<SizeContextProvider>
<Device />
</SizeContextProvider>
)
}
Here Device Component use Context Api
const Device = () => {
const { isMobile, isDesktop } = useSizeContext();
return (
<div>
{isMobile && <h1> Small Device </h1>}
{isDesktop && <h1> Largest Device </h1>}
</div>
);
}