Antd에서 List의 Colunm의 수를 width 마다 정해주는 기능을 지원하지 않아 직접 설정해야 했다.
당연히 window object에 접근해 width의 값을 가져오려고 하는데 계속해서 에러가 떴다.
window,document is not defined
왜 그런가 찾아보았더니 Next.js에서 서버에서 웹페이지를 렌더링 할 땐 window와 같은 document등의 object가 없기 때문이었다. 그렇기 때문에 클라이언트 사이드 렌더링에서 작동할 수 있도록 코드를 짜야했다.
const useWindowSize = () => {
const isClient = typeof window === "object";
const getSize = () => {
return { width: isClient ? window.innerWidth : undefined };
};
const [windowSize, setWindowSize] = useState(getSize);
useEffect(() => {
if (!isClient) {
return false;
}
const handleResize = () => {
setWindowSize(getSize());
};
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, []);
return windowSize;
};
isClient 변수를 통해 클라이언트 사이드 렌더링에서만 작동하게 한다. 그리고 getSize 함수를 통해 width의 값을 가져 온다.
const [windowSize, setWindowSize] = useState(getSize);
그리고 windowSize를 통해 width의 값을 state에 넣어 useEffect를 통해 클라이언트 사이드 렌더링과 width이 변경 될 때 state의 값도 변경 된다.
useEffect(() => {
if (!isClient) {
return false;
}
const handleResize = () => {
setWindowSize(getSize());
};
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, []);
width 값이 바뀔 때마다 이전 값을 삭제해주고 계속해서 업데이트를 해줘야하는데 return을 통해 이벤트를 제거했다.
그렇게 깔끔하게 반응형을 구현했다.