React와 styled-components를 이용한 반응형 이미지 변경 방법

BossTeemo·2024년 8월 7일
0

문제해결노트

목록 보기
6/7
post-thumbnail
post-custom-banner

React기반으로 next.js와 Styled-compoents를 사용해
사이드프로젝트를 진행하던 도중
화면사이즈에따라 다른이미지를 보여줘야하는 경우가 생겼다.
이를 구현하기위해 알아보다가 두가지 방법을 알게되었고,
이에 대해 정리해보고자한다.


방법 1: React 상태와 효과를 이용한 방법

이 방법은 React의 useStateuseEffect 훅을 사용하여 화면 크기를 감지하고, 상태(state)를 통해 이미지 소스를 변경하는 방법입니다.

import React, { useState, useEffect } from 'react';
import styled from 'styled-components';
import Image from 'next/image';
import Title from './Title';
import SubTitle from './SubTitle';

const BannerContainer = styled.div`
  position: relative;
  width: 100vw;
  height: 90vh;
  margin-bottom: 10vh;
  display: flex;
  justify-content: center;
  align-items: center;
  overflow: hidden;
  background: linear-gradient(
    180deg,
    #4facfe 0%,
    rgba(0, 242, 254, 0.8) 31.5%,
    #ffffff 100%
  );
`;

const BackgroundImage = styled(Image)`
  width: 100%;
  height: auto;
  object-fit: cover;
  @media (max-width: 768px) {
    object-fit: contain;
  }
`;

const TitleContainer = styled.div`
  z-index: 10;
  width: 80%;
  max-width: 1200px;
  height: 85%;
  white-space: nowrap;
`;

const Banner = () => {
  const [src, setSrc] = useState('/images/BannerImage.svg');

  useEffect(() => {
    const handleResize = () => {
      if (window.innerWidth < 768) {
        setSrc('/images/MobileImage.svg');
      } else {
        setSrc('/images/BannerImage.svg');
      }
    };

    window.addEventListener('resize', handleResize);

    // 초기 로드 시 실행
    handleResize();

    return () => {
      window.removeEventListener('resize', handleResize);
    };
  }, []);

  return (
    <BannerContainer>
      <BackgroundImage
        fill
        src={src}
        alt="Banner Image"
        priority
      />

      <TitleContainer>
        <Title />
        <SubTitle />
      </TitleContainer>
    </BannerContainer>
  );
};

export default Banner;

장점:

  1. 직관성: 상태 변화를 명확하게 다루며, 코드가 비교적 직관적입니다.
  2. 유연성: 다양한 조건에 따라 이미지를 쉽게 변경할 수 있습니다.
  3. 리액트 방식: React 훅을 사용하여 상태 변화를 관리할 수 있습니다.

단점:

  1. 추가 렌더링: 상태 변경으로 인해 불필요한 렌더링이 발생할 수 있습니다.
  2. 복잡성 증가: 단순한 이미지 변경을 위해 추가적인 코드가 필요합니다.

방법 2: styled-components와 props를 활용한 방법

이 방법은 styled-components의 attrs를 이용하여 props를 통해 조건부 스타일링을 적용하는 방법입니다.

import React from 'react';
import styled from 'styled-components';
import Image from 'next/image';
import Title from './Title';
import SubTitle from './SubTitle';

const BannerContainer = styled.div`
  position: relative;
  width: 100vw;
  height: 90vh;
  margin-bottom: 10vh;
  display: flex;
  justify-content: center;
  align-items: center;
  overflow: hidden;
  background: linear-gradient(
    180deg,
    #4facfe 0%,
    rgba(0, 242, 254, 0.8) 31.5%,
    #ffffff 100%
  );
`;

const BackgroundImage = styled(Image).attrs(props => ({
  src: props.isMobile ? '/images/MobileImage.svg' : '/images/BannerImage.svg'
}))`
  width: 100%;
  height: auto;
  object-fit: cover;
  @media (max-width: 768px) {
    object-fit: contain;
  }
`;

const TitleContainer = styled.div`
  z-index: 10;
  width: 80%;
  max-width: 1200px;
  height: 85%;
  white-space: nowrap;
`;

const Banner = () => {
  const [isMobile, setIsMobile] = React.useState(false);

  React.useEffect(() => {
    const handleResize = () => {
      setIsMobile(window.innerWidth < 768);
    };

    window.addEventListener('resize', handleResize);

    // 초기 로드 시 실행
    handleResize();

    return () => {
      window.removeEventListener('resize', handleResize);
    };
  }, []);

  return (
    <BannerContainer>
      <BackgroundImage
        fill
        isMobile={isMobile}
        alt="Banner Image"
        priority
      />

      <TitleContainer>
        <Title />
        <SubTitle />
      </TitleContainer>
    </BannerContainer>
  );
};

export default Banner;

장점:

  1. 코드 간결성: props를 통해 styled-components에서 조건부 스타일링을 바로 적용할 수 있습니다.
  2. 렌더링 효율성: 상태 변경이 최소화되어 불필요한 렌더링이 줄어듭니다.
  3. 스타일링 통합: styled-components 내에서 스타일링과 로직을 모두 처리할 수 있습니다.

단점:

  1. 유연성 부족: 조건이 더 복잡해지면 코드가 복잡해질 수 있습니다.
  2. 디버깅 어려움: styled-components의 attrs를 통한 동적 props 적용은 디버깅이 어려울 수 있습니다.

결론

  • 간단한 경우: 만약 간단한 조건부 이미지 변경이 필요하다면, styled-components와 props를 활용한 방법이 더 적합할 수 있습니다.
  • 복잡한 경우: 더 복잡한 로직이나 조건이 필요한 경우, React 상태와 효과를 이용한 방법이 더 유연하고 관리하기 쉬울 수 있습니다.

이 두 가지 방법을 상황에 맞게 적절히 사용하여 반응형 디자인을 구현해보세요. 필요할 때마다 이 글을 참고하여 구현 방식을 선택하면 좋겠습니다.

profile
1인개발자가 되겠다
post-custom-banner

0개의 댓글