While using the MUI useMediaQuery
hook, I noticed my react app being buggy and throwing errors because the hook initially does not recognise the correct breakpoint, then the page quickly re-renders with the correct value.
Example:
const mobile = useMediaQuery((theme) => theme.breakpoints.only('mobile'));
console.log(mobile)
Console:
false
true
What's going on?
While using the MUI useMediaQuery
hook, I noticed my react app being buggy and throwing errors because the hook initially does not recognise the correct breakpoint, then the page quickly re-renders with the correct value.
Example:
const mobile = useMediaQuery((theme) => theme.breakpoints.only('mobile'));
console.log(mobile)
Console:
false
true
What's going on?
Share Improve this question edited Sep 21, 2021 at 10:25 benmneb asked Jul 23, 2021 at 10:40 benmnebbenmneb 2,3032 gold badges23 silver badges30 bronze badges2 Answers
Reset to default 13This is the expected behaviour of useMediaQuery
hook. It's explained in the MUI docs:
To perform the server-side hydration, the hook needs to render twice. A first time with false, the value of the server, and a second time with the resolved value. This double pass rendering cycle es with a drawback. It's slower. You can set this option to true if you are doing client-side only rendering.
So to get the correct value on the first page render the noSsr
option in the useMediaQuery
hook needs to be true
.
There are two options:
1) Per ponent:
const mobile = useMediaQuery((theme) => theme.breakpoints.only('mobile'), {noSsr: true});
2) Globally in the theme
object:
const theme = createTheme({
ponents: {
MuiUseMediaQuery: {
defaultProps: {
noSsr: true,
},
},
}
Obviously, this will only work without server-side rendering.
The original answer below works in Material-UI v4, but the Hidden
ponent has been deprecated in v5.
Original answer:
I realised that by removing the media query and replacing it with the Material-UI <Hidden />
ponent it works how I want it to.
export const ResponsiveMenuItem = forwardRef((props, ref) => {
const { children, ...other } = props;
return (
<>
<Hidden smUp>
<option ref={ref} {...other}>
{children}
</option>
</Hidden>
<Hidden only="xs">
<MenuItem ref={ref} {...other}>
{children}
</MenuItem>
</Hidden>
</>
);
});
I had same problem and went from
const breakpointDownLg = useMediaQuery(theme.breakpoints.down("lg"));
{breakpointDownLg ? <Navigation /> : <DesktopNavigation /> }
to
<Box sx={{ display: { lg: "none" } }} >
<Navigation />
</Box>
<Box sx={{ display: {xs: "none", lg: "block" } }}>
<DesktopNavigation />
</Box>
This seem to work https://mui./material-ui/migration/v5-ponent-changes/#hidden