[TIL] Next.js 에서 styled-components 적용 문제

JulyK9·2023년 2월 8일
0
post-thumbnail

이번에 유데미에서 Nextjs를 배우면서 프로젝트에 적용해보고 싶었다.

프로젝트에 사용할 스택을 정하는 과정에서
css는 styled-components를 사용하기로 했는데,
프론트를 나혼자 하려다보니 속도를 고려해야겠다는 생각이 들었고
나에게 익숙한 스택이면서도
더 연습하고 활용할 부분도 많다고 생각되어 styled-components로 정하게 되었다.

문제발생

우선 이번 문제는 네비게이션바를 스타일링 하면서 생겼다.

정상적으로 작동 되다가도 변경된 스타일링을 적용할 때
정확히 말하자면 첫 렌더링 때는 문제가 없다가 새로고침을 하면
콘솔창에 아래와 같은 경고가 뜨면서 스타일링이 모두 해제되는 증상이었다.

서버와 클라이언트에서 각각 부여된 클래스네임이 일치하지 않는다는 내용이었다.
Nextjs는 SSR 또는 SSG를 기본으로 사용해 사전 렌더링을 하는데
이때 initial load에서 HTML을 미리 로드하고나서
hydration 과정에서 다른 파일을 로드하면서 클래스네임이 달라지기 때문

해결방법

방법1.

이렇게 달라지는 클래스네임을 바벨 플러그인(babel-plugin-styled-components)을 통해
잡아줄 수 있다.

먼저 바벨을 설치하고

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 (사용되지 않는 속성 제거)
      }
    ]
  ]
}

방법2.

nextjs가 12버전 부터는 바벨대신 SWC를 통한 컴파일링을 하기 때문에
nextjs 13버전을 설치한 나는 이 방법을 적용해서 해결하였다.
CNA(Create-Next-App)을 통해 프로젝트를 만들면
next.config.js 파일이 생성되는데
여기서 styledComponents 설정을 해주면 문제를 해결할 수 있다.
공식문서를 참고하여 위와 같이 세부옵션을 설정해줄 수도 있다.

/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
  // 설정
  compiler: {
    styledComponents: true,
  },
};

module.exports = nextConfig;

참고자료

[Next.js] Next.js에서 Prop className did not match 경고가 뜨는 이유
https://tesseractjh.tistory.com/164
[Next.js] renderPage 함수로 styled-components 오류 방지하기
https://wonit.tistory.com/369
[정직하게 배워보는 Next js] Next.js의 두 번째 핵심 Pre-Rendering
https://wonit.tistory.com/362?category=829651
Next.js에서 Styled-components 적용하기
https://velog.io/@leejpsd/Next.js%EC%97%90%EC%84%9C-Styled-components-%EC%A0%81%EC%9A%A9%ED%95%98%EA%B8%B0
Nextjs 바벨에서 SWC로 이사가기
https://kir93.tistory.com/entry/NextJS-Babel%EC%97%90%EC%84%9C-SWC%EB%A1%9C-%EC%9D%B4%EC%82%AC%EA%B0%80%EA%B8%B0

profile
느리지만 꾸준하게. 부족하거나 잘못된 부분은 알려주시면 감사하겠습니다.

0개의 댓글