icecream 프로젝트를 하던 도중 반응형 네브바를 만들어보자는 생각이 들어서 반응형 웹을 공부하다가 React-responsive라는 라이브러리를 알게되었고, 좀 더 깔끔하게 코드작성을 할 수 있을 것 같고, 컴포넌트화를 할 수있기 때문에 사용해보기로 했다.
react-responsive는 반응형 앱을 구현하기 위한 react의 라이브러리로 mediaquery를 이용하여 화면크기, 해상도 등에 따라 각기 다른 컴포넌트를 구현 할 수 있다.
npm install react-responsive --save
먼저 반응형 앱을 만들기 위해 관리할 컴포넌트를 만들어 주었다.
//Responsive.ts
import { useMediaQuery } from 'react-responsive';
interface Props {
children: JSX.Element;
}
export const Mobile = ({ children }: Props): JSX.Element | null => {
const isMoblie = useMediaQuery({ maxWidth: 767 });
return isMoblie ? children : null;
};
export const DeskTop = ({ children }: Props): JSX.Element | null => {
const isDeskTop = useMediaQuery({ minWidth: 768 });
return isDeskTop ? children : null;
};
여기서 useMediaQuery는 react-responsive에서 제공해주는 훅으로,viewport의 크기를 감지하고, 이에 따라 다른 스타일, 동작을 적용하는데 사용한다.
매개변수로 미디어 쿼리 문자열을 받고, 지정된 쿼리와 일치하는지 여부를 나타내는 불린(Boolean) 값을 반환한다.
Mobile 과 DeskTop은 컴포넌트를 Props로 받는다.
Mobile은 최대 넓이가 767 이하이면 true를 반환하여 children을 리턴하고, DeskTop은 최대 넓이가 768 이상이면 true를 반환하여 children을 리턴하는 로직이다.
import React from 'react';
import { Mobile, DeskTop } from 'src/responsive/Responsive';
import DesktopNav from './DeskTop';
import MobileNav from './Mobile';
const NavBar = () => {
return (
<>
<DeskTop children={<DesktopNav />} />
<Mobile children={<MobileNav />} />
</>
);
};
Nav 컴포넌트이다. 여기서는 Responsive.tsx에서 export한 함수들을 감싸고 사용한다.
Props로 실제 보여줄 컴포넌트들을 children으로 내려준다.
컴포넌트들을 각자 나눠주면서 모바일 화면일때와 PC화면일때의 컴포넌트들을 나누어서 보여지게 하였다.