styled-components는 쓰면 쓸수록 진국이다.
재밌고 편리하고 재활용 가능한 기능들도 꽤나 있고, 까도까도 재밌는 것만 나오는 양파같은 스탈컴포넌ㅌ.
물론 css-in-js중 에서 점유율이 조금씩 떨어지고 있지만..
회사에서 Next.js 를 사용하기로 결정이 된 후
React를 할 때와 마찬가지로 styled-components를 적용 했는데
이게 웬걸 ..
화면들이 엄청나게 깜빡 거리는 것이다.
Next.js는 SSR로서 서버에서 Meta태그 등이 포함되어 있는 HTML을 먼저 만들어놓고 보여준 후 자바스크립트를 동적으로 추가 시켜주어 것인데, css-in-js인 styled-components는 당연하게도 HTML 생성 이후에 적용이 되는 "JS"이기 때문에 깜빡! 거릴 수 밖에 없었다 .
Next.js에서는 기본적으로 보이지는 않지만 _app.js와 _document.js가 있다.
이 파일들을 생성해서 수정하면 custom하게 사용이 가능하다.
_document.js를 pages폴더에 생성한 후,
다음과 같은 코드를 입력하자.
import Document from "next/document";
import { ServerStyleSheet } from "styled-components";
export default class MyDocument extends Document {
static async getInitialProps(ctx) {
const sheet = new ServerStyleSheet();
const originalRenderPage = ctx.renderPage;
try {
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App) => (props) =>
sheet.collectStyles(<App {...props} />), //ServerStyleSheet를 사용해 정의된 모든 스타일을 수집하여 페이지가 렌더링되기 전에 props로 채워지도록 반환한다.
});
const initialProps = await Document.getInitialProps(ctx);
return {
...initialProps,
styles: (
<>
{initialProps.styles}
{sheet.getStyleElement()}
</>
),
};
} finally {
sheet.seal();
}
}
}
주의할 점 : _document.js는 서버사이드 렌더링만 가능하며 React의 기능들을 사용할 수 없다.
babel plugin 을 설치하자.
yarn add -D babel-plugin-styled-components
그후 루트 폴더에 .babelrc 파일을 만들어서 다음 코드를 입력하자.
{
"presets": [
"next/babel"
],
"plugins": [
[
"styled-components",
{
"ssr": true,
"displayName": true,
"preprocess": false
}
]
]
}
이유를 계속 찾았지만 계속해서 깜빡이다가!
오늘이 되어서야 이유를 찾았다.
개발자도구에 Network tab을보니 re-render가 될때 마다, Font파일들이 reload되는 것이다.
휴.... 그래도 원인을 발견해서 다행이었다.
기존에는 이런식으로 GlobalStyle에 font-face들을 넣어주고 다른 style들을 적용하듯이
이런식으로 _app.js에 적용해 주었다.
그래서 방법이 뭐냐고 .... 폰트를 뺄 순 없었다. 그래서 구글링을 계속한 결과... 두둥...
GlobalStyle에서 나오는 그런 오류? 같은 것 같다.(확실힌 모름 .. )
결국 font-face들을 빼고 모두 템플릿 리터럴에 담은후
이런식으로 _app.js의 style태그안에 담게 되었다.
원래는
<style jsx global>
을 사용하려고 했으나, 계속해서
위와 같은 오류가 발생해서 결국 <style>
태그안에 감싸고 모든 깜빡임이 해결 되었다.
안녕하세요 좋은 해결방법 감사합니다. 저 같은 경우는 로 넣으면 싱글쿼트가 치환되서 폰트 로드가 안됐습니다. 그래서 <style dangerouslySetInnerHTML={{ __html: fontFace }} />로 변경해주니까 되네용!