[React] React-Responsive / 반응형 웹 만들기

SeokHun·2021년 2월 19일
40

React

목록 보기
2/4

1. Responsive Web

태플릿, PC, 모바일 등 다양한 해상도로 접근할 때 동일한 서비스를 제공하기 위한 웹

반응형 웹은 모바일 기기에서도 불편함이 없는 서비스를 제공하기 위해 각 해상도에 따라서 레이아웃과 스타일 변화를 준다.

1-1. Media Query

CSS 2.1 부터 미디어 타입으로 단말기 종류에 따라서 다른 스타일을 적용시키는 것이 가능했다.
하지만 기기의 특성을 정확히 판단하기가 어려워 많이 사용되지는 않았다.

CSS 3은 미디어 타입을 개선하여 구체적인 조건을 필요한 스타일을 적용할 수 있도록 확장하였는데 이를 미디어 쿼리라고 한다.

Syntax

  • only|not
    • only : 뒤의 조건에서 만
    • not : 뒤의 조건을 제외한
  • 미디어 타입
    • all : 모든 미디어 타입
    • aural : 음성 합성 장치
    • braille : 점자 표시 장치
    • handheld : 손으로 들고 다니면서 볼 수 있는 작은 스크린에 대응
    • print : 인쇄 용도
    • projection : 프로젝터
    • screen : 컴퓨터 스크린
    • tty : 디스플레이 능력이 한정된 털렉스, 터미널, 수동 이동 장치 등 고정 된 글자를 사용하는 미디어
    • tv : 음성과 영상이 동시 출력되는 장치
    • embrossed : 페이지에 인쇄된 점자 표시 장치
  • 속성
    • width : 웹 페이지의 가로 길이
    • height : 웹 페이지의 세로 길이
    • device-width : 단말기의 가로 길이
    • device-height : 단말기의 세로 길이
    • orientation : width 와 height 을 구해
      width > height 일 경우 landscape
      height > width 일 경우 portrait
    • aspect-ratio : width / height 비율
    • device-aspect-ratio : 단말기의 물리적인 화면 비율
    • color-index : 단말기에서 사용하는 최대 색상 수
    • monochrom : 흑백 컬러만을 사용하는 단말기에서 흰색과 검은색 사이의 단계
    • resolution : 지원하는 해상도를 판단
    • color : 단말기에서 사용하는 최대 색상 수의 비트 수
      (2의 지수를 뜻한다) ex) 1 은 2, 2 는 4, 3 은 8

1-2. Fluid Grid

그리드의 폭을 고정 값이 아닌 em 또는 %의 값으로 설정하는 것을 뜻한다.
가로 폭의 길이의 변화에 따라서 컬럼의 크기가 상대적으로 변하게 하는 방법이다.

레이아웃에는 변화가 없을 수 있으므로 폭이 많이 좁은 모바일에서 큰 효과를 볼 수 없을 수 있다.

1-3. Liquid Layouts

유동형 그리드와 같이 반응형 웹 기법 중 하나이다.
레이아웃 크기를 유동형 그리드와 같이 상대적 단위로 지정하여 웹의 크기에 따라 유동적으로 변화를 준다.
반응형 그리드와 같이 미디어 쿼리를 사용하여 일정 크기가 되면 레이아웃 구조를 바꾸어 준다.

2. in React ?

위에서 반응형 웹 경우 HTML/CSS 만으로도 구현이 가능한 경우이다.

하지만 반응형 웹을 만들고 디자인하다 보면 구조나 기능 자체를 다르게 해야하는 경우가 있다.
ex) PC 에서는 길게 늘어져 있던 메뉴가 모바일에선 메뉴 버튼으로
ex) 디자인을 위해 순서를 바꿔 놓는 경우 ... etc

JS에서 이를 구현할 수 있는 많은 방법이 있다.

이 페이지에서는 react-responsive 의 훅을 이용해 구현하는 방법을 알아보고자 한다.

2-1. react-responsive

npm : react-responsive

react-responsive 모듈 설치
npm install react-responsive

typescript 를 사용하는 경우 추가 설치
npm install @types/react-responsive

2-2. useMediaQuery

react-responsive 에서 제공하는 useMediaQuery 훅을 사용해보자.

import React from 'react'
import { useMediaQuery } from 'react-responsive'
 
const Example = () => {
  const isDesktopOrLaptop = useMediaQuery({ minDeviceWidth: 1224 })
  const isBigScreen = useMediaQuery({ minDeviceWidth: 1824 })
  const isTabletOrMobile = useMediaQuery({ maxWidth: 1224 })
  const isTabletOrMobileDevice = useMediaQuery({ maxDeviceWidth: 1224 })
  const isPortrait = useMediaQuery({ orientation: 'portrait' })
  const isRetina = useMediaQuery({ minResolution: '2dppx' })
 
  return (
    <div>
      ...
    </div>
  )
}

공식 문서의 예제와 같이 위의 내용을 작성해서 변수를 사용할 수 있다.

해당 변수는 조건에 맞는지 아닌지에 대한 true / false 가 들어가게 된다.
특정 상황에서만 출력을 하도록 하고 싶다면 아래와 같은 예제를 만들 수 있다.

import { useMediaQuery } from 'react-responsive'
 
const Example = () => {
  const isDesktopOrLaptop = useMediaQuery(
     { minDeviceWidth: 1224 },
     { deviceWidth: 1600 } // `device` prop
  )
 
  return (
    <div>
      {isDesktopOrLaptop &&
        <p>
          this will always get rendered even if device is shorter than 1224px,
          that's because we overrode device settings with 'deviceWidth: 1600'.
        </p>
      }
    </div>
  )
}

Easy Mode

공식 문서에 Context를 사용하는 방법 / onChange callback을 사용하는 방법이 있으므로 보는 것도 좋을 것 같다.

맨 아래에 있는 내용 중 제일 유용할 것 같은 예제를 가져와 봤다.

import { useMediaQuery } from 'react-responsive'
 
const Desktop = ({ children }) => {
  const isDesktop = useMediaQuery({ minWidth: 992 })
  return isDesktop ? children : null
}
const Tablet = ({ children }) => {
  const isTablet = useMediaQuery({ minWidth: 768, maxWidth: 991 })
  return isTablet ? children : null
}
const Mobile = ({ children }) => {
  const isMobile = useMediaQuery({ maxWidth: 767 })
  return isMobile ? children : null
}
const Default = ({ children }) => {
  const isNotMobile = useMediaQuery({ minWidth: 768 })
  return isNotMobile ? children : null
}
 
const Example = () => (
  <div>
    <Desktop>Desktop or laptop</Desktop>
    <Tablet>Tablet</Tablet>
    <Mobile>Mobile</Mobile>
    <Default>Not mobile (desktop or laptop or tablet)</Default>
  </div>
)
 
export default Example

마무리

한 가지 방법에만 묶여있지 말고 여러가지 방법을 사용해 보도록 하자~!!~!~!

참고

CSS:반응형 웹(Responsive Web)

npm : react-responsive

2개의 댓글

comment-user-thumbnail
2022년 1월 27일

좋은 요약 감사합니다!!

답글 달기
comment-user-thumbnail
2023년 7월 24일

딱 제가 찾던거에요! 감사합니다!

답글 달기