React, Next, Redux/🚀 React with Hooks
useState와 useEffect로 반응형 레이아웃 구현하기
DarrenKwonDev
2020. 8. 9. 14:17
반응형을 제외하고, 단순히 모바일인지 브라우저인지를 감지하기 위해서는
React에서는 react-useragent 패키지를 통해서 UA로 모바일을 감지하는 게 더 나은 것 같네요.
Next면 서버 사이드 측에서 UA를 감지하면 됩니다.
import { withUserAgent } from "react-useragent";
function isMobile() {
if (ua.mobile) return true;
return false;
}
export default withUserAgent(PaymentForm);
왜 Styled-Componenent + Media Query를 사용하지 않느냐고 물을 수 있는데, 이번에 toast ui를 사용하게 되면서 위 조합을 사용할 수 없게 되었다. 스타일링을 하는 방식이 다음과 같았기 때문이다.
상대값도 잘 먹지 않아서 다른 방법을 찾아야 했다.
const myTheme = {
"common.border": "1px solid #e5e5e5",
"common.backgroundColor": "white",
"common.holiday.color": "#ff4040",
"common.saturday.color": "#333",
"common.dayname.color": "#333",
"common.today.color": "#333",
// creation guide style
"common.creationGuide.backgroundColor": "rgba(81, 92, 230, 0.05)",
"common.creationGuide.border": "1px solid #515ce6",
}
스타일링으로 덮는 것이 아니라 가로 길이를 탐지해서 특정 조건을 만족하면 아예 다른 Theme을 적용하게 해야했다. resize 이벤트를 이용해서 이를 탐지해보도록 하자.
https://developer.mozilla.org/en-US/docs/Web/API/Window/resize_event
현재 프로젝트에서 1023 이하로는 모두 모바일뷰로 처리하기로 했기 때문에 1023을 기준으로 잡았습니다.
function Event() {
const [isMobile, setisMobile] = useState(false);
// 리사이즈 이벤트를 감지하여 가로 길이에 따라 모바일 여부 결정
const resizingHandler = () => {
if (window.innerWidth <= 1023) {
setisMobile(true);
} else {
setisMobile(false);
}
};
// 우선 맨 처음 1023이하면 모바일 처리
useEffect(() => {
if (window.innerWidth <= 1023) {
setisMobile(true);
}
window.addEventListener("resize", resizingHandler);
return () => {
// 메모리 누수를 줄이기 위한 removeEvent
window.removeEventListener("resize", resizingHandler);
};
}, []);
... 이하 return 내용 생략
스크롤과 브라우저 창 크기 관련된 작업들은 이벤트가 계속 발생하게 두면 무리가 갈 수 있죠.
여기서 더 fancy 하게 만들기 위해서는 resize 이벤트를 발생시킬 때 Throttle을 적용하여 너무 많은 이벤트를 발생시키지 않는 것이 좋습니다.