[ mdiea-query ] React 반응형 웹 레이아웃 만들기

유미정 Yu Mijung·2023년 7월 31일

반응형 웹이란?

PC, 모바일, 태블릿 등 다양한 디바이스에 맞는 해상도에 따라 레이아웃과 스타일에 최적화 해주어 사용자에게 편의성이 높은 UI 를 제공합니다.

React-responsive

React 애플리케이션에서 반응형 디자인을 쉽게 구현할 수 있도록 도와줄 수 있는 라이브러리 입니다.
다양한 장치 및 화면 크기에 따라 UI를 적절히 조정하여 사용자 경험을 향상시킬 수 있습니다.

  • MediaQuery : 화면 크기에 따라 컴포넌트 스타일을 적용할 수 있도록 지원합니다. (버튼의 크기, 색상 ..)
  • 반응형 컴포넌트 : 동일한 컴포넌트를 여러 번 작성하지 않고도 장치별로 다른 UI를 제공할 수 있습니다.
  • 미디어 유틸리티 : Javascript 코드 내에서 화면 크기에 따른 조건부 로직을 작성할 수 있습니다.
    • 1) 설치하기

      사용하고 있는 패키지에 따라 아래 react-responsive 라이브러리를 설치해줍니다.

      $ npm install react-responsive --save
      
      $ yarn add @react-responsive
      
      $ yarn add @types/react-responsive
      

      2) MediaQuery

      import MediaQuery from 'react-responsive'
      
      export default function App():JSX.Element {
      
          return(
              <>
              <MediaQuery query='(min-width: 600px)'>
                  {matches => {
                      return matches ? "hello" : "world";
                  }}     
              </MediaQuery>
      	  	<>

      3) useMediaQuery()

      customHook으로 분리할 수 있습니다.

      
      // 페이지에 반응형Hook 적용
      const matches = useMediaQuery("(min-width: 600px)");
      
      
      
      import { useState, useEffect } from "react"
      
      // useMediaQuery Hook 페이지 화면의 크기 감지
      export function useMediaQuery(query: string): any {
        const getMatches = (query: string): boolean => {
            // SSR issue 방지 (화면 크기를 조건문으로 확인한다.)
            if(typeof window !== 'undefined') {
                return window.matchMedia(query).matches
            }
            return false
        }
      
        // boolean 타입의 화면크기 값 담을 state 만들고 change 이벤트시 boolean 타입으로 저장  
        const [ matches, setMatches ] = useState<boolean>(getMatches(query))
        function handleChange() {
            setMatches(getMatches(query))
        }
      
        // 2) query로 가져온 화면 크기 감지될 때마다 렌더링 
        useEffect(() => {
            const matchMedia = window.matchMedia(query)
      
            // 화면 크기 저장 함수 호출
            handleChange()
      
            // 조건문 Event 감지 (렌더링 시점을 알 수 있도록 useEffect안에서 사용해야 한다.)
            // addEventListener를 통해 이벤트를 등록하고 난 뒤 이벤트 등록을 해제해주지 않으면, 계속해서 이벤트를 감지하기 때문에 성능 저하를 일으킬 수 있다. 그러므로 컴포넌트가 언마운트 될 때 꼭 이벤트 등록을 해제해주어야 한다.
            if(matchMedia.addListener) {
                matchMedia.addListener(handleChange)
            } else {
                matchMedia.addEventListener('change', handleChange)
            }
            
            return () => {
                if( matchMedia.removeListener) {
                    matchMedia.removeListener(handleChange)
                } else {
                    matchMedia.removeEventListener('change', handleChange)
                }
            }
        },[query])
      
        return matches;
        // boolean 타입으로 반환
      
      }
      
      
      
profile
안녕하세요 :) 유미정입니다.

1개의 댓글

comment-user-thumbnail
2023년 7월 31일

좋은 글이네요. 공유해주셔서 감사합니다.

답글 달기