How to use Material UI's 'useMediaQuery' with a class component

Viewed 1006

Im trying to use Material UI's useMediaQuery to modify the styles of one of Material UI's component, which is the Button component. I am trying to remove the outline around the button when the screen shrinks. So I was trying to do this:

    const mediumScreen = useMediaQuery(theme.breakpoints.down('md'));

 <Button
        name="discoverItems"
        variant={mediumScreen ? '' : 'outlined'}
        color="primary"
        size="small"
       >
        Shop Here
      </Button>

However, I am not using a functional component. Instead I am using a class component and it is throwing error:

TypeError: (0 , _core.useMediaQuery) is not a function

Is there any way I can achieve the goal without turning it into a functional component? Thanks!

1 Answers

There may be a variety of ways MaterialUI supports this, but more generally you can always wrap a class component with a function component to get hooks passed into a class component you don't plan to convert to a function component at the moment.

For example, if you class component looked something like this originally:

export default class MyComponent extends Component {
    render() {
        return (
            <Button name="discoverItems" color="primary" size="small">Shop Here</Button>
        );
    }
}

You could change that file to look like this:

export default function MyComponentWrapper({ ...rest }) {
    const mediumScreen = useMediaQuery(theme.breakpoints.down('md'));
    return <MyComponent {...rest} mediumScreen={mediumScreen} />;
}

class MyComponent extends Component {
    render() {
        const { mediumScreen } = this.props;
        return (
            <Button name="discoverItems" color="primary" size="small" variant={mediumScreen ? '' : 'outlined'}>Shop Here</Button>
        );
    }
}

The {...rest} parts just allow you to pass through any props. Any consumers of your original class component will not have to change. You're effectively asking that the mediumScreen be provided as a prop in your original class component and then providing a wrapping component that provides it.

This is sort of like an adapter pattern for hooks/class components.

Related