Notice
Recent Posts
Recent Comments
관리 메뉴

즐겁게, 코드

넥스트를 꾸며줘 : styled-jsx 활용하기 본문

🎨 프론트엔드/Next.js

넥스트를 꾸며줘 : styled-jsx 활용하기

Chamming2 2021. 2. 23. 23:02

기존 리액트 어플리케이션은 크게 두 가지 방법으로 스타일을 꾸밀 수 있었습니다.

하나는 CSS나 SASS 등 별도의 스타일 파일을 생성해 관리하는 방식이고, 다른 하나는 컴포넌트 안에서 스타일을 작성하는 CSS-in-Js 라는 방식입니다.

 

이중 넥스트(Next.js)에서는 CSS-in-js 방식을 권장하며, styled-component와 유사한 styled-jsx 라는 도구를 활용합니다.

styled-jsx

styled-jsx는 넥스트 프로젝트에 기본적으로 포함되어 있습니다.

이를 활용하기 위해서는 jsx 라는 값을 속성으로 갖는 style 태그를 컴포넌트 본문에 위치시킨 후, 적용할 CSS 스타일을 *문자열로 작성하면 됩니다.

(* 상태에 따른 조건부 스타일을 활용할 수 있다는 장점을 살리기 위해 주로 템플릿 문자열을 활용합니다.)

<>
  <div className="msg">Hello, World!</div>
  // `(템플릿 문자열)으로 감싸진 사실에 유의하세요!
  <style jsx>`
    .msg {
      font-size: 20px;
    }
  `</style>
</>

이제 스타일이 적용된 모습을 확인할 수 있습니다.

기본적으로 styled-jsx는 사용된 컴포넌트에만 영향을 미치며, 스타일을 전역으로 활용하기 위해서는 global 이라는 속성을 사용합니다.

<div>
  <div className="msg">Hello, World!</div>
  // 스타일 태그에 global 속성을 추가하면
  // 다른 컴포넌트의 .msg 요소에도 스타일을 입힐 수 있습니다.
  <style jsx global>`
    .msg {
      font-size: 20px;
    }
  `</style>
</div>

스타일 객체 활용하기

이번에는 스타일 태그 안에 모든 스타일을 작성하는 것보다 조금 더 세련된 방법을 사용해 보겠습니다.

import css from "styled-jsx/css";

// 스타일 객체
const style = css`
  .title {
    color: red;
  }
`;

// 컴포넌트 본체
const index = () => {
  return (
    <>
      <div className="title">Hello, World!</div>
      <style jsx>{style}</style>
    </>
  );
};

styled-jsx/css 모듈로부터 css 함수(객체)를 불러와 스타일을 분리할 수도 있습니다.

이러면 컴포넌트 내부의 비즈니스 로직과 스타일을 효과적으로 분리할 수 있게 되는데요, 다만 위 코드를 잘 살펴보면 컴포넌트와 분리되어있기에 상태값에 따라 스타일을 동적으로 부여할 수 없다는 치명적인 단점이 생깁니다.

스타일 스플리팅

이 문제를 해결하기 위해 정적인 스타일과 동적인(조건부) 스타일을 분리할 수 있습니다.

import css from "styled-jsx/css";
import { useState } from "react";

// 정적 스타일 (상태에 영향을 받지 않는)
const style = css`
  button {
    background-color: #ff23ff;
  }
`;

const index = () => {
  const [isRed, setIsRed] = useState(false);
  return (
    <>
      <div className="title">Hello, World!</div>
      <button
        onClick={() => {
          setIsRed((prev) => !prev);
        }}
      >
        색상 변경
      </button>
      <style jsx>{style}</style>
      // 동적인 스타일 (상태에 따라 색상 변경)
      <style jsx>
        {`
          .title {
            color: ${isRed ? "red" : "black"};
          }
        `}
      </style>
    </>
  );
};

export default index;

스타일 태그는 얼마나 있든 문제가 되지 않으니 상태에 영향을 받는 스타일은 컴포넌트 내에서 관리하고, 상태에 영향을 받지 않는 스타일은 css 객체를 활용해 컴포넌트 밖에서 관리하면 보다 깔끔하게 컴포넌트를 유지할 수 있습니다.

TL;DR

- 넥스트에서는 외부 CSS 파일 대신 styled-jsx 라는 방법을 사용한다.

- 상태에 영향을 받는 스타일은 컴포넌트 내에 작성하며, 상태에 영향을 받지 않는 스타일은 스타일 객체로 관리할 수 있다.

반응형
Comments
소소한 팁 : 광고를 눌러주시면, 제가 뮤지컬을 마음껏 보러다닐 수 있어요!
와!! 바로 눌러야겠네요! 😆