
How to handle responsive design in React
Hello and welcome in 2021 🥳. I didn't write for ages, glad to see you again.
Okay, alright. Today, let's talk about Responsive Web Design (also known as rwd) in a React context. (This also works with Next.js). As you may say, the most obvious way could be to use @media
in a CSS file, which makes totally sense as it is how it works.
But I'm not here for that. I'm here to show you different ways to handle Responsive Design which can be really helpful when you want to change more than only the CSS.
For that, we will use contra/react-responsive which is really good. You have multiple libs to handle our subject but this one also works with SSR (that's why I find it interesting for Next.js) and has a onChange
trigger which can be useful.
So, stop talking, let's see my solution.
Installation
1$ npm install react-responsive
Reference file
Let's create our main file. This is where you set all your responsive cases.
1// ./media-queries.js23const MQ = {4 "--tablet": "(max-width: 1279px)",5 "--desktop": "(min-width: 1280px)",6}78export default MQ
It will be our reference.
Hooks
Time to create our custom hooks.
1// ./src/hooks/media-queries.js23import { useMediaQuery } from "react-responsive"45import MQ from "media-queries"67export const useDesktopMediaQuery = () =>8 useMediaQuery({ query: MQ["--desktop"] })910export const useTabletMediaQuery = () =>11 useMediaQuery({ query: MQ["--tablet"] })
Components
Now, our components.
1// ./src/components/MediaQueries/index.js23import { useDesktopMediaQuery, useTabletMediaQuery } from "hooks/media-queries"45export const Desktop = ({ children }) => {6 const isDesktop = useDesktopMediaQuery()78 return isDesktop ? children : null9}1011export const Tablet = ({ children }) => {12 const isTablet = useTabletMediaQuery()1314 return isTablet ? children : null15}
Usage
That's great! As you can see, now we've got our references in one file, also some hooks if needed, and the components if you think it is easier to read. I assume here you've got @emotion/styled or styled-components for a certain part of this code.
Let's see how we can use it.
1// ./src/pages/index.js23import MQ from "media-queries"45import { useDesktopMediaQuery, useTabletMediaQuery } from "hooks/media-queries"67import { Desktop, Tablet } from "components/MediaQueries"89const Root = styled.div`10 {/* direct way */}11 @media ${MQ["--desktop"]} {12 {...}13 }1415 @media ${MQ["--tablet"]} {16 {...}17 }18`1920const IndexPage = () => {21 // hook way22 const isDesktop = useDesktopMediaQuery()23 const isTablet = useTabletMediaQuery()2425 if (isDesktop) {26 alert("Wow! Nice display screen!")27 }2829 return (30 <Root>31 {/* component way */}32 <Desktop>33 <LargeMap />34 </Desktop>3536 <Tablet>37 <BurgerIcon />38 </Tablet>3940 <Button fullWidth={isTablet}>{`My button`}</Button>41 </Root>42 )43}
This is perfect! Now, You have different ways depending on your context (jsx, style, etc), really easy to read.
Enjoy.