useMediaQuery
To provide an optimized experience on mobile, tablet, and desktop devices, you often need to display different components depending on the screen size. Material UI provides a hook dedicated to help such responsive layouts: useMediaQuery.
Usage
useMediaQuery expects a function receiving the Material UI theme as a parameter, and returning a media query. Use the theme breakpoints to check for common screen sizes. The hook returns a boolean indicating if the current screen matches the media query or not.
const isXSmall = useMediaQuery(theme => theme.breakpoints.down('xs'));
const isSmall = useMediaQuery(theme => theme.breakpoints.down('sm'));
const isDesktop = useMediaQuery(theme => theme.breakpoints.up('md'));
You can also pass a custom media query as a screen.
const isSmall = useMediaQuery('(min-width:600px)');
Tip: Previous versions of react-admin shipped a <Responsive> component to do media queries. This component is now deprecated. Use useMediaQuery instead.
Responsive Layouts
Here is an example for a responsive list of posts, displaying a SimpleList on mobile, and a Datagrid otherwise:
// in src/posts.js
import * as React from 'react';
import { useMediaQuery } from '@mui/material';
import { List, SimpleList, Datagrid, TextField, ReferenceField, EditButton } from 'react-admin';
export const PostList = () => {
    const isSmall = useMediaQuery(
        theme => theme.breakpoints.down('sm'),
        { noSsr: true }
    );
    return (
        <List>
            {isSmall ? (
                <SimpleList
                    primaryText={record => record.title}
                    secondaryText={record => `${record.views} views`}
                    tertiaryText={record => new Date(record.published_at).toLocaleDateString()}
                />
            ) : (
                <Datagrid>
                    <TextField source="id" />
                    <ReferenceField label="User" source="userId" reference="users">
                        <TextField source="name" />
                    </ReferenceField>
                    <TextField source="title" />
                    <TextField source="body" />
                    <EditButton />
                </Datagrid>
            )}
        </List>
    );
};
Responsive Styles
If you need to apply different styles depending on the screen size, use responsive values in the SX prop instead of calling the useMediaQuery hook manually
<Box
  sx={{
    width: {
      xs: 100, // theme.breakpoints.up('xs')
      sm: 200, // theme.breakpoints.up('sm')
      md: 300, // theme.breakpoints.up('md')
      lg: 400, // theme.breakpoints.up('lg')
      xl: 500, // theme.breakpoints.up('xl')
    },
  }}
>
  This box has a responsive width.
</Box>
Performance
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 comes with a drawback. Itβs slower. To avoid it, you can set the noSsr option to true if you are doing client-side only rendering.
const isSmall = useMediaQuery('(min-width:600px)', { noSsr: true });
TypeScript
useMediaQuery is generic, and can be used with a custom theme type:
import { useMediaQuery, Theme } from '@mui/material';
const MyComponent = () => {
    const isXsmall = useMediaQuery<Theme>(theme =>
        theme.breakpoints.down('sm')
    );
    // ...
};
