개발 공부 일지/React

[React] Emotion - React 컴포넌트 스타일링

dev-hpk 2025. 1. 6. 23:25

Emotion🤔

Emotion은 리액트에서 스타일을 관리하기 위한 CSS-in-JS 라이브러리로, 자바스크립트 코드 내에서 직접 CSS를 작성하고 적용할 수 있게 해 줍니다. Emotion 외에도 Styled-Components가 주로 사용됩니다.

 

2024 css-in-js 사용 추세

 

2024 css-in-js 사용 추세

지난 2년간 npm 다운로드 기록

지난 2년간 npm 라이브러리 다운로드 기록

Styled-Components 대신 Emotion을 선택한 이유🤔

Emotion을 선택한 첫 번째 이유는 styled-components는 이전 미션과 프로젝트를 통해 많이 경험해봤기 때문에 새로운 라이브러리를 경험해 보고 싶어서입니다. 트렌드를 따라가는 것도 좋지만 여러 라이브러리를 사용해 보면 왜 특정 라이브러리가 많이 사용되는지 비교해 볼 수 있을 것 같습니다😊 

두 번째 이유는 자주 참조하는 toss에서 Emotion을 주 기술로 사용하고 있다는 점입니다. Emotion을 활용해봄으로써 실제 기업에서 사용되는 기술을 배우고, 그 효율성이나 장점들을 직접 경험할 수 있는 좋은 기회라고 생각했습니다.

 

위 내용은 개인적인 이유이니, Emotion을 사용했을 때 장점도 알아봐야겠죠❓

💡Emotion의 장점

  1. 동적 스타일링 지원 : 컴포넌트의 props나 state에 따라 스타일을 동적으로 변경할 수 있어, 다양한 상태에 따른 스타일링이 가능합니다.
  2. 서버 사이드 렌더링(SSR) 지원 : Emotion은 Next.js와 같은 서버 사이드 렌더링 환경에서 별도의 설정 없이 동작해 SSR을 구현할 때 편리합니다.
  3.  
  4. 작은 번들 크기 : Emotion은 Styled-Components에 비해 번들 크기가 작아, 애플리케이션의 로딩 속도를 향상시킬 수 있습니다.

styled-components 번들 크기
emotion 번들 크기

 

이제 프로젝트에 emotion을 적용해 보겠습니다❗

Emotion 설치 및 import

npm install @emotion/react @emotion/styled

설치가 완료되면 아래와 같이 import 해서 사용할 수 있습니다.

import { css } from '@emotion/react';
import styled from '@emotion/styled';

 

import 까지 끝났으니 이제 emotion/react와 emotion/styled를 사용하는 방법을 각각 예시로 확인해 보겠습니다👀

@emotion/react 사용 예제

@emotion/react를 사용하여 스타일을 정의하고 css prop을 사용하여 리액트 컴포넌트에 적용하는 방식입니다.

toss github을 확인해보니 이 방법을 채택했네요❗

/** @jsxImportSource @emotion/react */
import { css } from '@emotion/react';

function App() {
  return (
    <div
      css={css`
        background-color: #000000;
        padding: 20px;
        border-radius: 8px;
      `}
    >
      <h1 
      	css={css`
      	  color: #ffffff;
          font-size: 30px;
          font-weight: bold;
      	`}>
      	Emotion React!
      </h1>
    </div>
  );
}

export default App;

 

  • /** @jsxImportSource @emotion/react */ 는 jsx 파일이 css prop을 읽을 수 있게 하기 위해 선언합니다.
  • css prop을 사용하여 인라인으로 스타일을 정의하고 HTML 요소에 바로 적용합니다.
  • 각 요소마다 css prop을 사용해 스타일을 개별적으로 지정할 수 있습니다.

@emotion/styled 사용 예제

@emotion/styled는 styled-components와 비슷한 방식으로 리액트 컴포넌트를 스타일링할 수 있게 해주는 API입니다. styled 함수는 스타일링 된 컴포넌트를 반환하고, 이 컴포넌트를 JSX에서 사용할 수 있습니다. 이는 리액트의 컴포넌트와 스타일을 결합하는 선언적인 방식입니다.  

import styled from '@emotion/styled';

const Wrapper = styled.div`
  background-color: lightblue;
  padding: 20px;
  border-radius: 8px;
`;

const Title = styled.h1`
  color: #ffffff;
  font-size: 30px;
  font-weight: bold;
`;

function App() {
  return (
    <Wrapper>
      <Title>Emotion Styled!</Title>
    </Wrapper>
  );
}

export default App;

 

 

  • styled.div와 styled.h1을 사용하여 스타일링된 Wrapper와 Title 컴포넌트를 생성합니다.
  • styled를 사용하면 해당 컴포넌트를 재사용 가능하고 선언적으로 스타일링할 수 있습니다.

두 방법 모두 동적 스타일링이 가능하고, 애플리케이션의 요구사항에 맞는 스타일링 방식을 선택하시면 될 것 같네요😊

 

저는 Styled-Components와 유사한 점과 스타일링된 컴포넌트를 생성하고 여러 곳에서 재사용할 수 있다는 점에서 @emotion/styled 방식을 선택했습니다❗

 

프로젝트에 적용해 보니 컴포넌트를 재사용할 수 있고 동적으로 스타일링 할 수 있다는 점에서 너무 만족스러웠어요.

 

@emotion/styled 예시: 동적 스타일링

import styled from '@emotion/styled';
import { useState } from 'react';

// styled-components로 테마에 따라 스타일 변경
const Container = styled.div<{ darkMode: boolean }>`
  background-color: ${(props) => (props.darkMode ? '#000' : '#fff')};
  color: ${(props) => (props.darkMode ? '#fff' : '#000')};
  padding: 20px;
  border-radius: 8px;
  transition: background-color 0.3s, color 0.3s;
`;

const Button = styled.button`
  background-color: blue;
  color: white;
  border: none;
  padding: 10px 20px;
  cursor: pointer;
  border-radius: 4px;

  &:hover {
    background-color: green;
  }
`;

function App() {
  const [darkMode, setDarkMode] = useState(false);

  return (
    <Container darkMode={darkMode}>
      <h1>{darkMode ? 'Dark Mode' : 'Light Mode'}</h1>
      <Button onClick={() => setDarkMode(!darkMode)}>Toggle Theme</Button>
    </Container>
  );
}

export default App;

 

  • Container는 darkMode prop을 사용하여 스타일을 동적으로 변경합니다. darkMode가 true일 때 검정 배경색을, false일 때 하얀 배경색을 적용합니다.
  • Button 컴포넌트는 클릭 시 darkMode 상태를 토글하여, 전체 UI의 테마를 변경합니다.

@emotion/styled 예시: 재사용 가능한 컴포넌트

import styled from '@emotion/styled';

// 스타일링된 Button 컴포넌트 생성
const Button = styled.button<{ primary?: boolean }>`
  background-color: ${(props) => (props.primary ? 'blue' : 'gray')};
  color: white;
  padding: 10px 20px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 16px;
  transition: background-color 0.3s;

  &:hover {
    background-color: ${(props) => (props.primary ? 'darkblue' : 'darkgray')};
  }
`;

function App() {
  return (
    <div>
      <Button primary>Primary Button</Button>
      <Button>Secondary Button</Button>
    </div>
  );
}

export default App;

 

 

 

  • Button 컴포넌트는 styled.button을 사용하여 버튼 스타일을 정의합니다.
  • primary prop을 통해 버튼의 배경색을 동적으로 변경할 수 있습니다.
  • primary prop이 true이면 파란색 배경, false이면 회색 배경이 적용됩니다.
  • @emotion/styled를 사용하여 컴포넌트를 정의하고, 이 컴포넌트를 여러 곳에서 재사용할 수 있습니다.

 

Emotion을 사용해보고 느낀 점📕

Emotion을 사용해 보면서 단점을 딱히 느끼지 못했습니다. 오히려 좋은 점이 훨씬 많았는데요, 간단하게 정리해 보겠습니다.

  • props와 state를 이용한 동적 스타일링이 가능해 편리하다.
  • scss 문법을 사용할 수 있어 편리하다.
  • scss 문법에 js 함수, 조건문을 활용할 수 있어 편리하다.
  • 전역 스타일링과 테마 관리 기능을 제공해 다크 모드나 사용자 정의 스타일을 구현하는데 편리하다.

 

Emotion을 어떻게 사용했는지 궁금하신 분들을 위해 아래 제 github의 Design-System 레포지토리를 남겨두겠습니다.

부족하지만 참고해 보시고, 피드백도 남겨주신다면 감사하겠습니다😊

 

design-system/src/components at develop · hpk5802/design-system

Contribute to hpk5802/design-system development by creating an account on GitHub.

github.com

 

 

 

 

[React] 리액트 라이프사이클(Lifecycle)과 useEffect

React는 컴포넌트 기반의 라이브러리로, 모든 컴포넌트는 생명주기(Lifecycle)를 가집니다. 생명주기는 컴포넌트가 생성, 업데이트, 제거되는 과정을 의미하며 이를 활용해 컴포넌트의 특정 시점에

dev-hpk.tistory.com

 

 

 

[React] React Hook Form 라이브러리로 Form 간편하게 관리하기

React 애플리케이션에서 폼 관리는 매우 빈번한 작업입니다. React State를 이용해 폼 상태를 관리하고, 유효성을 검증하며, 성능을 최적화하는 것은 번거로울 수 있습니다. React Hook Form은 이러한 작

dev-hpk.tistory.com