문제
- 스타일이 적용되지 않은 html 코드가 먼저 렌더링되는 문제 발생
- Header 부분 표시하려고 스타일 컴포넌트 적용하니 오류 발생
원인
- 자바스크립트 코드가 적용이 되지 않은 페이지가 미리 렌더링되기 때문에 CSS-in-JS 로 스타일링을 하면 스타일이 적용되지 않은 html 코드가 먼저 렌더링 되는 문제가 발생하게 된다.
- Next.js는 첫 페이지 로드가 SSR로 동작 ⇒ 서버에서 생성된 컴포넌트와 CSR로 클라이언트에서 생성된 컴포넌트의 클래스명이 서로 달라진다.
해결
- html 파일에 CSS-in-JS 형식으로 작성된 스타일 요소들을 주입시켜서 스타일이 적용되지 않은 html 코드가 먼저 렌더링되는 문제를 해결할 수 있다.
- Next.js에서 styled-components를 사용할 때 ⇒ **_document**를 따로 설정해서 SSR될 때 CSS가 head에 주입되도록 만든다.
import Document, {
Html,
Head,
Main,
NextScript,
DocumentContext
} from 'next/document';
import { ServerStyleSheet } from 'styled-components';
class MyDocument extends Document {
static async getInitialProps(ctx: DocumentContext) {
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>
);
}
}
export default MyDocument;
- 환경에 따라 달라지는 className을 일관되게 해주는 라이브러리 설치
npm install --save-dev babel-plugin-styled-components
- 루트 디렉토리에 .babelrc 파일 생성
{
"presets": ["next/babel"],
"plugins": [
[
"babel-plugin-styled-components",
{
"ssr": true, // SSR을 위한 설정
"displayName": true, // 클래스명에 컴포넌트 이름을 붙임
"pure": true // dead code elimination (사용되지 않는 속성 제거)
}
]
]
}
참고 자료
https://velog.io/@eunnbi/NextJS-styled-components와-함께-사용하기
'개발 일지 > React' 카테고리의 다른 글
useRef (0) | 2023.04.04 |
---|---|
[NextJs] react-query(prefetching)로 SSR 구현 (0) | 2023.02.28 |
[Next.js] A title element received an array with more than 1 element as children. In browsers title Elements can only have Text Nodes as children. 경고 (0) | 2023.02.27 |
새로고침시 데이터에 undefined가 들어온다면 (0) | 2023.02.23 |
Next.js 에선 <img> 보다는 <Image> (0) | 2023.02.11 |