시계 컴포넌트
사이트 상단바에 현재 시각을 실시간으로 표시하는 시계 기능을 넣었다.
시계는 1초마다 렌더링을 발생시켜 주어진 함수에 의해 현재 시각을 체크한다. 그런데 이 부분이 Next.js의 서버 사이드 렌더링과 충돌하면서 런타임 에러가 발생했다. 브라우저에서만 동작하는 서드파티 라이브러리나 모듈을 사용할 때 종종 이런 이슈가 발생된다고 한다.
이 경우 서버 사이드 렌더링을 직접 해제해야만 한다. 컴포넌트가 window 객체 또는 로컬 스토리지 속성에 접근해야 한다면 서버 사이드 렌더링이 불필요하다. 프로젝트에서 서버 사이드 렌더링을 사용할지 여부는 개인의 선호도 문제이다.
export default function Clock() {
const language = useContext(LanguageContext);
const [currentTime, setCurrentTime] = useState<Date>(new Date());
useEffect(() => {
const interval = setInterval(() => {
setCurrentTime(new Date());
}, 1000);
return () => {
clearInterval(interval);
};
}, []);
// ...
const clock = `${period} ${String(twelveHourFormat).padStart(2, "0")}:${minutes}`;
return {clock};
}
Non-SSR 컴포넌트
아래 글을 참고해 NoSSR 컴포넌트를 만들어 Clock 컴포넌트를 감싸자 오류가 해결되었다. Next.js를 사용하는 이상 가급적 서버 사이드 렌더링을 유지하는 편이 좋겠지만, 아직까지는 더 나은 대안을 찾지 못했다.
Using Non-SSR Friendly Components with Next.js
How to disable SSR for Non-SSR Friendly Components in Next.js
blog.bitsrc.io
import * as React from "react";
interface Props {
children: any; // React.ReactNode
fallback?: any; // JSX.Element
}
const NoSSR = ({ children, fallback = null }: Props) => {
const [mounted, setMounted] = React.useState(false);
React.useEffect(() => setMounted(true), []);
if (!mounted) {
return fallback;
}
return children;
};
export default NoSSR;
export default function Clock() {
// ...
return <NoSSR>{clock}</NoSSR>;
}