React기반으로 next.js와 Styled-compoents를 사용해
사이드프로젝트를 진행하던 도중
화면사이즈에따라 다른이미지를 보여줘야하는 경우가 생겼다.
이를 구현하기위해 알아보다가 두가지 방법을 알게되었고,
이에 대해 정리해보고자한다.
이 방법은 React의 useState
와 useEffect
훅을 사용하여 화면 크기를 감지하고, 상태(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;
이 방법은 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;
styled-components
와 props를 활용한 방법이 더 적합할 수 있습니다.이 두 가지 방법을 상황에 맞게 적절히 사용하여 반응형 디자인을 구현해보세요. 필요할 때마다 이 글을 참고하여 구현 방식을 선택하면 좋겠습니다.