반응형
다음처럼 에러가 발생했다.
Prop `className` did not match. Server: "MuiTypography-root WithStyles(ForwardRef(Typography))-root-8 MuiTypography-h6" Client: "MuiTypography-root WithStyles(ForwardRef(Typography))-root-2 MuiTypography-h6" ... |
해당에러는 SSR 에서 생성된 className이 CSR 로 옮겨졌을 때 동일한 className을 찾지 못해 발생하는 에러다.
SSR은 next.js를 사용으며 해결법은 다음과 같다.
page/_document.js 파일을 만든 후 다음 코드를 삽입한다.
import React from "react";
import Document, {DocumentContext, Head, Html, Main, NextScript} from "next/document";
import {ServerStyleSheets} from "@material-ui/styles";
class AppDocument extends Document {
static async getInitialProps(ctx: DocumentContext) {
const sheet = new ServerStyleSheets();
const originalRenderPage = ctx.renderPage;
ctx.renderPage = () => originalRenderPage({
enhanceApp: App => props => {
return sheet.collect(<App {...props}/>)
}
});
const initialProps = await Document.getInitialProps(ctx);
return {
...initialProps,
styles: (
<>
{initialProps.styles}
{sheet.getStyleElement()}
{/*{sheetStyled.getStyleElement()}*/}
</>
)
}
}
render() {
return (
<Html>
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
export default AppDocument
그리고 바벨설정(.babelrc) 을 위해 설치 & 파일 내용을 수정한다
설치
npm i babel-plugin-styled-components
.babelrc 파일 수정
{
"presets": ["next/babel"],
"plugins": ["babel-plugin-styled-components"]
}
이제 새로고침 하면 제대로 스타일 반영 된다
참고)
비슷한 설정이 styled-component 에도 있는데 다음 참조하는 부분이 다르다
# material-ui 경우
import {ServerStyleSheets} from "@material-ui/styles";
# styled-component 의 경우
import {ServerStyleSheet} from "styled-components";
안에 들어있는 메서드도 다른데 각각 이렇다.
material-ui 경우
import * as React from 'react';
import { StylesProviderProps } from '../StylesProvider';
declare class ServerStyleSheets {
constructor(options?: object);
collect(children: React.ReactNode, options?: object): React.ReactElement<StylesProviderProps>;
toString(): string;
getStyleElement(props?: object): React.ReactElement;
}
export default ServerStyleSheets;
styled-components 경우
...
export class ServerStyleSheet {
collectStyles(tree: React.ReactNode): React.ReactElement<{ sheet: ServerStyleSheet }>;
getStyleTags(): string;
getStyleElement(): Array<React.ReactElement<{}>>;
interleaveWithNodeStream(readableStream: NodeJS.ReadableStream): NodeJS.ReadableStream;
readonly instance: this;
seal(): void;
}
...
그래서 중간에 삽입하는 구분인 sheet.collect의 경우도 styled-components 의 경우 collectStyles 를 호출해야 하며, 종종 finally 에 들어가는 곳에 sheet.seal() 이란 문구도 있는데 이역시 styled-components 를 설정할때 사용하는 것이다.
끝.
반응형
'공부 > 프로그래밍' 카테고리의 다른 글
[aws] s3 폴더 내 파일 public-read 권한 주기(aws cli 이용) (0) | 2021.03.24 |
---|---|
[react, redux, next, typescript] 프로젝트 만들때 최소 설정하는 것 정리 (0) | 2021.03.22 |
[gradle, springboot] multi project 설정하기 (1) | 2021.03.17 |
[react, next.js] SSR환경에서 access_token, refresh_tokne 관리하기(cookie이용) (2) | 2021.03.12 |
[swagger] ResourceServer 설정(HttpSecurity)으로 인해 UI접근이 안될 때 (0) | 2021.03.08 |
댓글