지난 글에서 @emotion/styled가 무엇인지, 어떤 패키지를 어떤 상황에 선택해야하는지를 얘기해봤는데요!!
이번 글은 실제로 @emotion/styled를 어떻게 사용하는지에 대해 집중적으로 다뤄보고자 합니다!!

이번 글은 @emotion/styled 공식 문서 기반입니다!
기본 개념은 ▶ 🔗 1편을 먼저 읽어 보신 뒤 읽어주시면 더욱 이해가 잘 될거에요!

▶ 🔗 공식 문서 이동 링크

1. props 기반 동적 스타일링

@emotion/styled 의 강점.
바로 props를 받아서 스타일을 동적으로 변경할 수 있다는 점입니다.

1-1. 기본 props 사용 방식

백틱 안에서 ${} 을 사용해 props에 접근이 가능합니다.
${} 안에 함수를 넣으면 props를 인자로 받습니다.
함수가 반환하는 값이 그대로 CSS 값으로 적용됩니다!

Object Style 방식도 동일하게 사용해요.

1-2. TypeScript 환경에서 props 타입 정의

TypeScript 환경에서는 props 타입을 제네릭으로 정의해야해요.
저는 이 제네릭 부분이 참 헷갈렸는데요!!
참고용으로 아래 헷갈릴만한 이론을 정리해뒀습니다!

📝참고용

  • () : props의 값을 받는 곳 ( ex. ( props ) => ... )
  • <> : 타입을 주입하는 제네릭 문법. styled에서는 props의 타입을 주입하는 데 사용
    ( ex. <{ active?: boolean }> )
  • <> 안의 내용 : 주입하는 타입 ( ex. { active?: boolean } )

타입을 정의하면 잘못된 props 전달을 컴파일 단계에서 바로 잡아줍니다!


2. shouldForwardProp

props 기반 스타일링을 하다 보면 아래와 같은 경고를 마주칠 수 있다고 합니다..!
( 흐음..전 만나본 기억은 없어용.. )

Warning: Received 'true' for a non-boolean attribute 'primary'

HTML 표준 속성이 아닌 커스텀 props가 DOM에 전달되면 발생하는 경고입니다.
HTML 표준 속성이 아닌 propsDOM에 전달되면 안되거든요!

이를 해결하는 것이 바로 shouldForwardProp입니다.

2-1.기본 사용법

shouldForwardPropfalse를 반환하는 propDOM에 전달되지 않고 스타일링에만 사용됩니다.

2-2. isPropValid 활용

커스텀 props가 많아질수록 하나씩 제외하는 방식은 번거롭습니다.
@emotion/is-prop-valid 패키지를 활용하면 HTML 표준 속성인지 자동 판별을 해줍니다.

isPropValid는 속성들에 대해 아래와 같이 반환합니다.

  • HTML 표준 속성(id, className, onClick 등) : true
  • 커스텀 속성(primary, active 등) : false

특정 커스텀 props만 추가로 제외하고 싶다면, 아래와 같이 조합이 가능합니다.

shouldForwardProp: (prop) => isPropValid(prop) && prop !== 'primary'

저는 커스텀 속성Sass에서 영감을 받은 $ prefix를 사용하여 표시하곤 합니다!!
$가 붙은 props는 HTML 표준 속성이 아니라는 게 한눈에 보여서, shouldForwardProp 설정 없이도 의도를 명확하게 전달할 수 있어요.

단, 실제로 $ prefix만으로는 DOM 전달을 막을 수 없고 shouldForwardProp은 여전히 필요해요!!!


3. 오버라이딩

3-1. styled( )로 컴포넌트 확장

styled(컴포넌트) 방식으로 기존 스타일을 확장할 수 있습니다.

BaseButton공통 스타일은 유지하되, 각각 다른 스타일만 추가했습니다.

변형이 많은 컴포넌트를 만들 때 중복을 줄이는 핵심 패턴이에요!!

실제로 제가 정말 많이 애용하는 패턴입니다!
디자인 시스템 만들때 좋아요!

단, styled(컴포넌트) 방식은
해당 컴포넌트가 className prop을 받을 수 있어야 합니다.
Emotion이 내부적으로 생성한 클래스명을 className으로 전달하는 방식이기 때문이에요!

3-2. as prop으로 렌더링 태그 변경

스타일은 그대로 유지하면서 렌더링되는 HTML 태그만 변경하고 싶을 때 as prop을 사용해요.
( 사실 저는 한번도 사용해보지 않았습니다..! )

아직 실무에서 직접 써볼 기회가 없었는데요,
버튼 컴포넌트를 <a> 태그로 렌더링해야 할 때나,
시맨틱 마크업(의미 있는 HTML 태그 사용)이 중요한 상황에서 유용할 것 같아요.
언젠가 써먹을 날이 오겠죠...?
아무튼 무척 편리한 방식이에요! 천재만재 개발자들!!


4. 실무에서 자주 사용되는 패턴

4-1. css helper로 동적 스타일 분리

props 기반 스타일이 복잡해질수록 백틱 안이 지저분해집니다.
css helper를 활용해 동적 스타일을 별도 변수로 분리하면 훨씬 깔끔해져요.
스타일 변형이 많은 디자인 시스템 컴포넌트에서 자주 사용합니다!!
( 강추 강추 강강추~ )

4-2. 조건부 스타일링 패턴

실제로 제가 가장 자주 쓰는 조건부 패턴들입니다!

삼항 연산자

: 2가지 중 한가지 선택 시

&& 연산자

: 조건이 true인 경우에만, 스타일 블록 전체를 적용할 때

객체 스프레드

: Object Style에서 조건부 속성을 추가할 때

아래 상황에 맞게 패턴을 선택해서 사용하면 된답니다!

  • 적용할 스타일이 1~2개 : 삼항 연산자
  • 여러 속성을 한 번에 적용 : && 연산자 or 객체 스프레드

저는 3가지의 스타일링 패턴 중 삼항 연산자&& 연산자css helper와 함께 자주 사용합니다!

Tailwind도 좋지만, 전 여전히 이 매력둥이에게 푹 빠져있답니다..❤️

다음 글은 @emotion/styled 기반으로 구현한 타이포 시스템 구현으로 돌아올게요!!

🔗 참고
Emotion 공식 문서 : https://emotion.sh/docs/styled

profile
바라는 색이 있다면 눈이 멀도록 바라볼 것. 가능한 온몸으로 부서질 것.

0개의 댓글