[TIL] React에서 Media Query 사용 [JS]

대빵·2023년 11월 13일

반응형 웹 (Responsive Web)

태블릿, PC, 모바일 등 다양한 기기에서도 불편함 없는 서비스를 동일하게 제공하기 위해 각 해상도에 따라 레이아웃과 스타일의 변화를 주어 제공하는 웹이다.

미디어 쿼리 (Media Query)

미디어 쿼리는 CSS에서 나온 기술로 특정 조건이 성립됐을 때 CSS 속성을 적용할 수 있게 해주는 문법이다.
특정 조건이란 화면의 넓이나 높이와 같이 브라우저가 어떤 기기에서 실행되고 있는지를 파악해서 기기별로 서로 다른 스타일을 제공하는 방법을 선택하는데, 이것을 반응형 프로그래밍이다.

사용 방법

@media screen and (max-width: 768px) {
  color: white;
  background-color: black;
}

screen영역이 768px 전 까지의 width에서 속성이 적용된다.

ThemeProvider를 이용한 미디어 쿼리 사용 방법

ThemeProvider 사용이유

라이브러리를 설치해서 사용하면 편리함은 있지만 라이브러리를 많이 설치하면 그렇게 좋지않아, 반응형 웹 작업에 ThemeProvider 사용을 하는 것이 스타일들을 관리하기에 효율적이다.

MediaQuery 자체 모듈화

media.js

  1. media.js는 미디어쿼리 자체를 내보낼 파일
  2. theme.js 통일화를 위해 정의된 다른 theme 속성
import { css } from "styled-components";

const breakPoints = {
  tablet: 800,
  laptop: 1200,
};

export default Object.key(breakPoints).reduce((acc, label) => {
  acc[key] = (...args) => css`
    @media (min-width: ${value}px) {
      ${css(...arg)}
    }
  `;
  return acc;
}, {});

Object.keys()
Object.keys()메소드는 객체(typeof 연산자로 확인했을 때 object가 반환되는)의 프로퍼티들 중에서 key값, 다른 말로는 프로퍼티 이름들만 묶어서 배열로 반환하는 메소드 입니다.

const object1 = {
  a: 'somestring',
  b: 42,
  c: false
};
const object1 = Object.keys(object1);
console.log(object1); // ["a", "b", "c"]

Object.keys()함수로 매개변수로 넘어간 breakPoints객체에 있는 enumerable 속성명을 가지고, reduce()의 리듀서 함수로 breakPoints에 정의된 값으로 acc 연산으로 각각의 media query의 속성들을 styled-components의 css 속성을 이용해서 만들어낸다.
그리고 그 속성 값들을 위에서 정의한 breakPoints객체에 있는 값들로 media query의 속성을 만드는데 ...args 문법으로 생성된 모든 args를 media query 내에 적용시켜준다.

기존 Media Query 적용

const Box = styled.div`
  /* props 로 넣어준 값을 직접 전달해줄 수 있습니다. */
  background: ${props => props.color || 'blue'};
  padding: 1rem;
  display: flex;
  
  /* 기본적으로는 1024px 에 가운데 정렬을 하고
    가로 크기가 작아짐에 따라 사이즈를 줄이고
    768px 미만으로 되면 꽉 채웁니다 */
  width: 1024px;
  margin: 0 auto;
  
  @media (max-width: 1024px) {
    width: 768px;
  }
  
  @media (max-width: 768px) {
    width: 100%;
  }
`;

Provider 적용

styled-components에서 ThemeProider를 적용하기 위해 만들어둔 theme.js파일을 import해와서 적용하고자하는 컴포넌트들에 감싸야 한다.

import { ThemeProvider } from "styled-components";
import Router from "./shared/Router";
import GlobalStyle from "./styledComponents/Globalstyle";
import theme from "./styledComponents/theme/theme";

export default function App() {
  return (
    <ThemeProvider theme={theme}>
      <GlobalStyle />
      <Router />
    </ThemeProvider>
  );

ThemeProvider 적용

theme={theme} -> theme={{...theme, ...media}}

const Box = styled.div`
  /* props 로 넣어준 값을 직접 전달해줄 수 있습니다. */
  background: ${props => props.color || 'blue'};
  padding: 1rem;
  display: flex;
  width: 1200px;
  margin: 0 auto;

  ${({ theme: { mediaQuery } }) => mediaQuery.tablet`
    width: 800px;
  `};

  ${({ theme }) => theme.mediaQuery.laptop`
  width: 1200px;
  `};
`;

0개의 댓글