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>
</>
);
}
참고 자료
'React' 카테고리의 다른 글
[React] React에서 Typescript + ESLint(Airbnb) + Prettier 적용하기 (0) | 2022.06.11 |
---|---|
[React] React에서 web-worker 사용하여 병렬 처리 하기 (0) | 2022.06.09 |
[React] Recoil (0) | 2022.05.02 |
[React] ESLint - Unexpected `await` inside a loop(no-await-in-loop) error (0) | 2021.08.04 |
[React] Typescript 상속을 이용해 라이브러리에 없는 타입 지정 (React+ Typescript + Plotly js) (0) | 2021.06.16 |