리액트에서 조건부 스타일을 줄때 classNames 라이브러리를 활용해보자!

둘둘·2020년 8월 23일
19
post-thumbnail

🤔 왜 쓰냐?

css modules를 쓰고 있는데 css를 쓸 때 객체형식으로 써야해서 불편하다!
css modules를 쓰지 않는다고 해도, 상태에 따라 클래스명을 부여해야할 경우 너무 지저분하다!!

🔧 설치

npm install classnames --save

설치만 하면 끝일줄 알았는데...

TS는 따로 설치해야 할 것이 있었음..

npm install --save @types/classnames

TS 쓰는 분들은 두번째꺼도 복붙 고고! 🙋🏻‍♀️
혹시나 하는 마음에.. 아래의 명령어를 복붙 후 1번 명령어로 설치한 classNames를 지웠더니 역시나 에러가..!


TS 쓰는 분들은 명령어 두 개 입력!
아닌 분들은 첫번째 것만 복붙 고!!

🌸 CSS MODULES에서의 활용

classNames 설치 전의 불편한 모습

import css from "./SidePannels.module.scss";

// 중략

   <div
     onClick={() => setIsOpen(!isOpen)}
     className={`${css[`path${path.length}`]}
     ${path.length === 3 && css.blueBg}
     `}>

// 중략

CSS MODULES는 위의 코드 예시처럼 css를 객체형으로 불러와서 dot notation 혹은 bracket notation으로 써야 한다.

template literal을 덕지덕지 쓰다보면 자꾸 Syntax error가 생기는데
위의 복잡한 코드를 요렇게 뙇!

설치 후의 e-편한 모습

import classNames from "classnames/bind";
import css from "./SidePannels.module.scss";

const cn = classNames.bind(css);


// 중략

    <div
      onClick={() => setIsOpen(!isOpen)}
      className={cn(`path${path.length}`,path.length === 3 && `blueBg`
     )}>
    
// 중략
  • bind를 해주지 않으면 css.을 계속 붙여 줘야 한다. 꼭 bind 해서 쓸 것!
  • template literal를 마구 마구 쓰지 않아도 된다. 걍 나열만 하면 된다!!
  • cn(이름은 자유롭게 설정!)으로 한 번 감싸주고, string 표시와 쉼표로 이름을 구분하면 된다.

더 복잡한 코드를 비교해보자 🤮

className이 여러개 일 때 - 지독한 케이스

<img
   className={`${css.pannelTriangle} 
   ${isOpen && path.length !== 3? css.pannelOpen: css.pannelClose} 
   ${path.length === 3 && css[`pannelArrow`]}
   ${!title && css[`imgNotFound`]} } />

보기만 해도 template literal에 삼항연산자에 뭔가 덕지덕지 더러워 보인다.
한 눈에 보기 쉽지 않다!

className이 여러개 일 때 - 행복한 케이스

<img
  className={cn(
  "pannelTriangle",
  isOpen && path.length !== 3 ? "pannelOpen" : "pannelClose",
  path.length === 3 && "pannelArrow",
  !title && "imgNotFound" )} />

길이만 따지고 보면 별 차이 없어 보이지만,
template literal을 안 쓰니까 훨씬 가독성이 좋아졌다!
이미지로도 비교해보자면...

B4

F털

정답은 갓 classNames 🙋🏻‍♀️

profile
Dooreplay! 안 되면 될 때까지,

1개의 댓글

comment-user-thumbnail
2023년 1월 10일

ㅋㅋㅋ 글이 너무 재밌고 유익합니다!

답글 달기