728x90
CSS-In-JS 방식인 Styled-components로 스타일을 다 하였지만,
리렌더링이 될 시 스타일이 적용이 안되는 문제가 발생하였다.
NextJS의 렌더링 및 스타일이 깨지는 이유를 알아보자
Next.js는 기본적으로 페이지를 ServerSide Rendering을 한다.
즉, pre-render을 한다는 것이다.
Server Side에서 html파일을 구성하여 브라웆 측에 전달하여 렌더링한다.
이후, JavaScript 파일이 로드되어 자바스크립트 코드가 적용된다.
즉, HTML → JavaScript로 인해 스타일이 적용되지 않은 html코드가 먼저 렌더링이 된다!
해결법
renderPage 함수를 커스터마이징하자!
Next.js 공식 홈페이지에서 CSS-In-JS 방식을 사용할 때만 수정하라고 나와있다.
pages/_document.ts파일을 만들고 아래와 같이 수정해주면된다.
import Document, {
Html,
Head,
Main,
NextScript,
DocumentContext,
DocumentInitialProps,
} from 'next/document';
import { ServerStyleSheet } from 'styled-components';
export default class MyDocument extends Document {
static async getInitialProps(ctx: DocumentContext): Promise<DocumentInitialProps> {
const sheet = new ServerStyleSheet();
const originalRenderPage = ctx.renderPage;
try {
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: App => props => sheet.collectStyles(<App {...props} />),
});
const initialProps = await Document.getInitialProps(ctx);
return {
...initialProps,
styles: [
<>
{initialProps.styles}
{sheet.getStyleElement()}
</>,
],
};
} finally {
sheet.seal();
}
}
render() {
return (
<Html>
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
위 코드와 같이 적용을 하면, pre-render할 때, 스타일도 보이는 것을 확인할 수 있다.
이후, className에 대한 콘솔에러가 뜨는 것을 확인할 수 있다.
바벨 파일을 설치
yarn add babel-plugin-styled-components
.babelrc 파일 생성
{
"presets": ["next/babel"],
"plugins": [
[
"styled-components",
{
"ssr": true,
"displayName": true,
"preprocess": true
}
]
]
}
위 코드를 작성 후, 서버를 껏다키면 에러가 없어지는 것을 확인할 수 있다.
728x90