React

[React] react-responsive 반응형 라이브러리 + Typescript

판교너굴맨 2022. 5. 11. 07:54

React를 사용한 토이 프로젝트를 진행하면서 반응형을 고려하게 되었다. 반응형을 구현할 때 가장 많이 접했을만한 미디어쿼리를 사용할까 했다가  react-responsive라이브러리를 추천 받아서 사용해보려고 한다.

1. 설치

# npm
npm i react-responsive
# yarn
yarn add react-responsive

Typescript를 사용한다면 아래 명령어를 추가한다.

# npm
npm install @types/react-responsive
# yarn 
yarn add @types/react-responsive

2. useMediaQuery

react-responsive 라이브러리는 useMediaQuery라는 Hook을 제공합니다.

import React from "react";
import { useMediaQuery } from "react-responsive";

export default function App(): JSX.Element {
  const isDesktop: boolean = useMediaQuery({
    query: "(min-width:1024px)",
  });
  const isTablet: boolean = useMediaQuery({
    query: "(min-width:768px) and (max-width:1023px)",
  });
  const isMobile: boolean = useMediaQuery({
    query: "(max-width:767px)",
  });

  return (
    <div>
      <h1>반응형 테스트</h1>
      {isDesktop && <p style={{ background: "red" }}>Desktop</p>}
      {isTablet && <p style={{ background: "blue" }}>Tablet</p>}
      {isMobile && <p style={{ background: "green" }}>Mobile</p>}
    </div>
  );
}

useMediaQuery Hook에 조건을 지정해주면 조건에 대해 true 또는 false를 반환합니다.

반환된 true, false로 화면 크기에 따라 각각 다른 화면을 출력할 수 있습니다.

 

화면 크기에 따라 출력되는 Text를 하나의 변수에 할당하고 싶다면 아래와 같이 하면 된다.

import React from "react";
import { useMediaQuery } from "react-responsive";

export default function App(): JSX.Element {
  const isDesktop: boolean = useMediaQuery({
    query: "(min-width:768px)",
  });
  const responsiveText = isDesktop ? "Desktop" : "Mobile";
  return <>{responsiveText}</>;
}

4. useMediaQuery 컴포넌트로 사용

아래와 같이 컴포넌트로 사용하면 재사용성이 늘어나게 된다.

mediaQuery.ts

import { useMediaQuery } from "react-responsive";

const Desktop = ({children}: {children: JSX.Element}): JSX.Element | null => {
  const isDesktop = useMediaQuery({ minWidth: 1024 });
  return isDesktop ? children : null;
};

const Tablet = ({children}: {children: JSX.Element}): JSX.Element | null => {
  const isTablet = useMediaQuery({ minWidth: 768, maxWidth: 1023 });
  return isTablet ? children : null;
};

const Mobile = ({children}: {children: JSX.Element}): JSX.Element | null => {
  const isMobile = useMediaQuery({ maxWidth: 767 });
  return isMobile ? children : null;
};

// mobile이 아닐 때만 출력되는 컴포넌트
const Default = ({children}: {children: JSX.Element}): JSX.Element | null => {
  const isNotMobile = useMediaQuery({ minWidth: 768 });
  return isNotMobile ? children : null;
};

App.tsx

import React from "react";
import { Default, Desktop, Mobile, Tablet } from "assets/mediaQuery";

export default function App(): JSX.Element {
  return (
    <>
      <Desktop>
        <p>Desktop or laptop</p>
      </Desktop>
      <Tablet>
        <p>Tablet</p>
      </Tablet>
      <Mobile>
        <p>Mobile</p>
      </Mobile>
      <Default>
        <p>Not mobile (desktop or laptop or tablet)</p>
      </Default>
    </>
  );
}

 

참고 자료

NPM 문서

 

react-responsive

Media queries in react for responsive design. Latest version: 9.0.0-beta.7, last published: 18 hours ago. Start using react-responsive in your project by running `npm i react-responsive`. There are 898 other projects in the npm registry using react-respons

www.npmjs.com