내일배움캠프
230808 useViewport()로 미디어 쿼리 없이 반응형 만들기
Neda
2023. 8. 8. 20:31
230808 useViewport()로 미디어 쿼리 없이 반응형 만들기
이번 프로젝트는 처음부터 반응형을 고려하고 만들기로 했다. Ant Design 라이브러리를 사용하기 때문에 전체 레이아웃은 Ant Design의 Layout 컴포넌트를 사용했다.Ant Disign에서는 Layout 컴포넌트를 import 한 다음 구조분해할당을 통해 다시 빼는 방식을 사용했다.
이렇게 사용하기 때문에 Header 컴포넌트를 자동완성으로 가져올 수는 없다
import { Layout } from 'antd';
const { Header, Content, Footer, Sider } = Layout;
<Layout.Header></Layout.Header>
<Header></Header>
Layout 컴포넌트를 반응형으로
이러한 Layout 컴포넌트에는 style props를 통해 직접 스타일 지정해 줄 수도 있지만, width속성을 통해 숫자나 문자열로 값을 지정할 수도 있다. 이 부분을 뷰포트 사이즈에 따라 바꿔주면 미디어 쿼리 없이도 반응형을 할 수 있었다.
import { Layout } from 'antd'
const { Sider } = Layout
const Sidebar = ({open, setOpen}:Props) => {
const {width} = useViewport()
return (
<Sider width={width < 800 ? '100%': 360} ...>
...
</Sider>
)
}
export default Sidebar
useViewport()
이 커스텀 훅은 직접 구현할까 하다가 저번에 본 글이 기억나 가져와서 사용하게 되었다.
역할은 resize()가 될 때마다 window 전역 객체에서 innerWidth, innerHeight 값을 가져와서 가지고 있는다.
더 발전시키면 Mobile, Table, Desktop 와 같이 3개 이상으로 더 세분화하여 나눌 수 있을 것 같다
import {
useLayoutEffect,
useState,
} from 'react';
function useViewport() {
const [width, setWidth] = useState(0);
const [height, setHeight] = useState(0);
const [isMobile, setIsMobile] = useState(false);
const [isLoaded, setIsLoaded] = useState(false);
const handleResize = () => {
setWidth(window.innerWidth);
setHeight(window.innerHeight);
setIsMobile(window.innerWidth <= 768 || window.outerWidth <= 768);
};
useLayoutEffect(() => {
handleResize();
setIsLoaded(true);
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
return {
width,
height,
isMobile,
isLoaded,
};
}
export default useViewport;
styled-components 환경에서 효율적으로 반응형 처리하기
조금 더 리액트스럽게 퍼블리싱 하기 위한 고민을 담았습니다.
blog.payhere.in