๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
  • ์žฅ์›์ต ๊ธฐ์ˆ ๋ธ”๋กœ๊ทธ
๐Ÿ“บ Front End/- React, Next.js

[Next.js] renderPage ํ•จ์ˆ˜๋กœ styled-components ์˜ค๋ฅ˜ ๋ฐฉ์ง€ํ•˜๊ธฐ.

by Wonit 2021. 1. 3.

React ์—์„œ ์Šคํƒ€์ผ๋ง์„ ์œ„ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ๋Š” ๊ฐœ์ธ์ ์œผ๋กœ ๋‹จ์—ฐ styled-components๊ฐ€ ์••๋„์ ์œผ๋กœ ์ข‹๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค.

 

ํ•˜์ง€๋งŒ Next์—์„œ๋Š” styled-components๊ฐ€ ์ œ๋Œ€๋กœ ๋™์ž‘ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋‹ค.

 

์˜ค๋Š˜ ๊ทธ ์˜ค๋ฅ˜๋“ค์„ ๋ถ„์„ํ•ด๋ณด๊ณ  ์–ด๋–ป๊ฒŒ ํ•˜๋ฉด ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์•Œ์•„๋ณด์ž.

๊ทธ๋ƒฅ styled-components๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ์–ด๋–ค ๋ฌธ์ œ๊ฐ€ ์ƒ๊ฐ€๋‚˜์š”?

Next.js ์•ฑ์—์„œ styled-components๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์Šคํƒ€์ผ์ด ์ ์šฉ๋˜์ง€ ์•Š๊ณ  ์ผ์ • ์‹œ๊ฐ„ ์ดํ›„์— ์Šคํƒ€์ผ์ด ์ ์šฉ๋œ๋‹ค.

๋งˆ์น˜ CSS ํŒŒ์ผ์ด ๋กœ๋“œ๋˜์ง€ ์•Š๋‹ค๊ฐ€ ๊ฐ‘์ž๊ธฐ ๋กœ๋“œ๋˜๋Š” ๊ฒƒ ์ฒ˜๋Ÿผ ๋ณด์ด๋Š”๋ฐ, ์ด๋Š” UX์—์„œ ๋‚˜์œ ํ‰๊ฐ€๋กœ ๊ฐ์ธ๋  ์ˆ˜ ์žˆ๊ณ  ์‚ฌ์šฉ์ž์—๊ฒŒ ์•„์ฃผ ๋ถˆ์พŒํ•œ ๊ฒฝํ—˜์„ ์„ ์‚ฌํ•  ์ˆ˜ ์žˆ๋‹ค.

์™œ ๊ทธ๋Ÿฐ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธฐ๋‚˜์š”?

Next๋Š” ์šฐ์„  ๋ชจ๋“  ํŽ˜์ด์ง€๊ฐ€ Pre-Render ๋œ๋‹ค๊ณ  ์ง€๋‚œ ์‹œ๊ฐ„์— ๋ฐฐ์› ์—ˆ๋‹ค.

 

์ด๋Ÿฐ Pre-Render์—๋Š” 2๊ฐ€์ง€ Stage๊ฐ€ ์กด์žฌํ•˜๋Š”๋ฐ,

  1. Initial Load Stage
  2. Hydration Stage

๊ฐ๊ฐ์˜ Stage์— ๋Œ€ํ•ด์„œ ๊ฐ„๋žตํžˆ ์„ค๋ช…ํ•˜์ž๋ฉด, Initial Stage์—์„œ Staticํ•˜๊ฒŒ ์ƒ์„ฑ๋œ HTML์ด ๋ Œ๋”๋œ ํ›„, Hydration Stage์—์„œ ๋‚˜๋จธ์ง€ JS ํŒŒ์ผ๋“ค์ด ๋กœ๋“œ๋˜์–ด Sync๋œ๋‹ค.

 

๊ฒฐ๊ตญ ์šฐ๋ฆฌ๊ฐ€ getStaticProps๋‚˜ getStaticPaths๋กœ SSG๋ฅผ ์ด์šฉํ•ด staticํ•œ HTML์„ ๋งŒ๋“ค์–ด SSR(SSG) ํ™˜๊ฒฝ์„ ๊ตฌ์ถ•ํ–ˆ๋‹ค๊ณ  ์น˜๋”๋ผ๋„ JS์— ์˜ํ•ด ๋™์ ์œผ๋กœ CSS๊ฐ€ ์ƒ์„ฑ๋˜๋Š” CSS-In-Js ๋ฐฉ์‹์ธ styld-components๋Š” SSG ๊ณผ์ •์—์„œ ์ƒ์„ฑ๋˜๋Š” HTML์— ์šฐ๋ฆฌ์˜ ์ฝ”๋“œ๊ฐ€ ํ•จ๊ป˜ Build ๋˜์ง€ ์•Š๊ฒŒ ๋œ๋‹ค.

 

์ด๋ฅผ ํ•œ ๋ฌธ์žฅ์œผ๋กœ ์ด์•ผ๊ธฐ ํ•œ๋‹ค๋ฉด,

 

Next.js๋Š” SSRํ˜น์€ SSG๋ฅผ ๊ธฐ๋ณธ์œผ๋กœ ์‚ฌ์šฉํ•ด์„œ Pre-Rendering ์„ ํ•˜๋ฉด์„œ Initial Load ๊ณผ์ •์—์„œ ๋ฏธ๋ฆฌ HTML์„ ๋กœ๋“œํ•˜๊ณ  Hydration ๊ณผ์ •์—์„œ ๋‹ค๋ฅธ ํŒŒ์ผ๋“ค์„ ๋กœ๋“œํ•˜๊ธฐ ๋–„๋ฌธ์— ๋ฐœ์ƒํ•œ๋‹ค.

 

๋กœ ๋งํ•  ์ˆ˜ ์žˆ๋‹ค.

์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‚˜์š”?

 

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์€ Next.js ๊ณต์‹ ํ™ˆํŽ˜์ด์ง€์—์„œ ์ด์•ผ๊ธฐํ•˜๋Š” renderPage ํ•จ์ˆ˜๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ณต์‹ ํ™ˆํŽ˜์ด์ง€์—์„œ๋Š” renderPage ํ•จ์ˆ˜๋ฅผ ์ปค์Šคํ„ฐ๋งˆ์ด์ง•ํ•˜๋Š” ๊ฒƒ์€ ์˜ค๋กœ์ง€ CSS-in-js ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•  ๋–„๋งŒ ์‚ฌ์šฉํ•˜๋ผ๊ณ  ๋‚˜์™€์žˆ๋‹ค.

 

๊ทธ๋ฆฌ๊ณ  ์šฐ๋ฆฌ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ๊ฒƒ์ด๋‹ค.

 

  • pages ๋””๋ ‰ํ† ๋ฆฌ์— Next ์•ฑ์˜ HTML Custom ์„ค์ •์„ ํ•  ์ˆ˜ ์žˆ๋Š”_document.js ํŒŒ์ผ์„ ์ƒ์„ฑ
  • ServerStyleSheet ํ•จ์ˆ˜๋ฅผ styled-components์—์„œ import ํ•˜์—ฌ Globalํ•˜๊ฒŒ ์„ค์ •
  • renderPage ํ•จ์ˆ˜๋กœ ๋ Œ๋”๋ง ์กฐ๊ฑด Customizing.

 

1. _document.js ํŒŒ์ผ ์ƒ์„ฑ

pages ๋””๋ ‰ํ† ๋ฆฌ ์•„๋ž˜์— _document.js ํŒŒ์ผ์„ ์ƒ์„ฑํ•œ๋‹ค.
next๋Š” _document.js ํŒŒ์ผ์„ Build ์‹œ์ ์— env ํŒŒ์ผ๋กœ ๊ฐ„์ฃผํ•˜๊ณ  ์ƒ๋žตํ•œ๋‹ค.

import Document, { Html, Head, Main, NextScript } from 'next/document'

class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const initialProps = await Document.getInitialProps(ctx)
    return { ...initialProps }
  }

  render() {
    return (
      <Html>
        <Head />
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    )
  }
}

export default MyDocument

 

2. ServerStyleSheet ํ•จ์ˆ˜ import

_document.js์—์„œ SC์˜ ServerStyleSheet๋ฅผ import ํ•œ๋‹ค.

// ... ์ƒ๋žต
import { ServerStyleSheet } from 'styled-components';
// ... ์ƒ๋žต

 

3. renderPage ํ•จ์ˆ˜ ์กฐ๊ฑด ์ถ”๊ฐ€.

_document.js ์—์„œ renderPage ํ•จ์ˆ˜ ์ถ”๊ฐ€.

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} />)
        });

      const initialProps = await Document.getInitialProps(ctx);
      return {
        ...initialProps,
        styles: (
          <>
            {initialProps.styles}
            {sheet.getStyleElement()}
          </>
        )
      };
    } finally {
      sheet.seal();
    }
  }
}

 

๊ทธ๋ฆฌ๊ณ  ๋‹ค์‹œ ์‹คํ–‰์‹œํ‚ค๊ฒŒ ๋œ๋‹ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •์ƒ์ ์œผ๋กœ styled-components๊ฐ€ ์ž˜ ๋™์ž‘ํ•˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

 

๋Œ“๊ธ€