WEB개발이야기/웹퍼블리싱

Classnames vs. clsx: 당신에게 딱 맞는 CSS 클래스 조합 도구는?

어쩌다보니여기까지~ 2024. 2. 26. 18:46
반응형

React에서 동적으로 클래스 이름을 조작하는 것은 흔히 발생하는 작업입니다. 이 작업을 간편하게 해주는 두 라이브러리가 바로 classnamesclsx입니다. 이 글에서는 두 라이브러리의 장점과 단점, 특이할 만한 사항 등을 비교 분석하여 개발자들이 각 라이브러리의 특성을 파악하고 적절하게 선택하는 데 도움을 드리고자 합니다. 또한 그 중에서 최근에 더 곽광을 받고 있는 clsx에 대해서 자세히 살펴보겠습니다.

1. Classnames

classnames는 클래스 이름을 조합하고 조건부로 적용하는 데 사용되는 유틸리티 라이브러리입니다. 다음과 같은 특징을 지닙니다.

장점:

  • 직관적인 API: classnames는 객체 형식으로 클래스 이름을 정의하여 간결하고 직관적인 코드를 작성할 수 있도록 합니다.
  • 다양한 사용 방식: classnames는 배열, 문자열, 객체 등 다양한 형태의 클래스 이름을 지원합니다.
  • 널널한 사용: classnames는 널리 사용되고 활발하게 유지되는 라이브러리입니다.

단점:

  • 성능 문제: classnames는 객체를 사용하기 때문에 성능 측면에서 다소 비효율적일 수 있습니다.
  • 문법 오류 감지 어려움: classnames는 문법 오류를 런타임까지 감지하지 못해 디버깅 과정을 어렵게 만들 수 있습니다.

특이사항:

  • classnames는 falsy 값을 자동으로 제거하여 불필요한 클래스 이름을 포함하지 않도록 합니다.
  • classNames는 최신 버전에서 dedupe 옵션을 제공하여 중복된 클래스 이름을 제거하는 기능을 추가했습니다.

2. clsx

clsx는 classnames와 유사한 기능을 제공하는 라이브러리이지만, 성능 개선과 문법 오류 감지 기능을 강화하여 다음과 같은 차별성을 지닙니다.

장점:

  • 뛰어난 성능: clsx는 템플릿 리터럴을 사용하여 객체 생성 없이 클래스 이름을 조합하여 성능을 향상시킵니다.
  • 문법 오류 감지: clsx는 TypeScript를 사용하여 문법 오류를 컴파일 타임에 감지할 수 있도록 합니다.
  • 간결한 코드: clsx는 템플릿 리터럴 문법을 사용하여 간결하고 가독성이 높은 코드 작성을 가능하게 합니다.

단점:

  • 덜 직관적인 API: classnames에 비해 템플릿 리터럴 문법에 대한 이해가 필요하여 다소 익숙하지 않을 수 있습니다.
  • 제한적인 기능: clsx는 classnames에 비해 객체 형식의 클래스 이름 정의 기능 등 일부 기능을 지원하지 않습니다.

특이사항:

  • clsx는 falsy 값을 자동으로 제거하고 중복된 클래스 이름을 처리하는 기능을 기본적으로 제공합니다.
  • clsx는 다양한 조건부 연산자를 지원하여 다양한 상황에 맞게 클래스 이름을 조건부로 적용할 수 있도록 합니다.

npm 트렌드를 살펴보면 계속 Classnames이 상위권에 속해 있었으나 근래들어 clsx가 역전을 한것을 볼 수 있습니다. 그래서 이 포스팅에서는 clsx에 대해서 좀더 알아보고 실제 예제 코드를 활용하여 사용법을 알아보도록 하겠습니다.

clsx 사용하기

1. 설치

clsx는 NPM 또는 Yarn을 사용하여 쉽게 설치할 수 있습니다. 아래의 설치방법 중 자신에게 맞는 한가지 방법만 사용하시면 됩니다.

npm install clsx --save 

or

yarn add clsx 

2. 기본 사용

clsx는 템플릿 리터럴을 사용하여 클래스 이름을 조합하고 조건부로 적용할 수 있습니다.

import clsx from 'clsx'; // or import { clsx } from 'clsx';  // 문자열 (가변) clsx('foo', true && 'bar', 'baz'); //=> 'foo bar baz'  // 객체 clsx({ foo:true, bar:false, baz:isTrue() }); //=> 'foo baz'  // 객체 (가변) clsx({ foo:true }, { bar:false }, null, { '--foobar':'hello' }); //=> 'foo --foobar'  // 배열 clsx(['foo', 0, false, 'bar']); //=> 'foo bar'  // 배열 (가변) clsx(['foo'], ['', 0, false, 'bar'], [['baz', [['hello'], 'there']]]); //=> 'foo bar baz hello there'  // Kitchen sink (중첩) clsx('foo', [1 && 'bar', { baz:false, bat:null }, ['hello', ['world']]], 'cya'); //=> 'foo bar hello world cya' 

3. 조건부 연산자 사용

clsx는 다양한 조건부 연산자를 지원하여 다양한 상황에 맞게 클래스 이름을 조건부로 적용할 수 있습니다.

const type = 'primary'; const size = 'large';  const className = clsx('button', { [`button-${type}`]: type, [`button-${size}`]: size, });  <button className={className}>버튼</button>; 

위 코드에서 type과 size 변수에 따라 button-primary, button-large, 또는 두 클래스 모두가 버튼에 적용됩니다.

4. 객체 형식 사용

classnames와 유사하게 객체 형식으로 클래스 이름을 정의할 수도 있습니다.

const styles = { button: 'button', active: 'active', disabled: 'disabled', };  const className = clsx(styles.button, { [styles.active]: active, [styles.disabled]: !active, });  <button className={className}>버튼</button>; 

위 코드에서 styles 객체에 정의된 클래스 이름을 사용하여 코드를 더욱 명확하게 작성할 수 있습니다.

5. 기타 기능

clsx는 다양한 유용한 기능을 제공합니다.

  • 중복된 클래스 이름 제거: 중복된 클래스 이름은 자동으로 제거되어 코드의 효율성을 높입니다.
  • 문법 오류 감지: TypeScript를 사용하는 경우 문법 오류를 컴파일 타임에 감지할 수 있습니다.

6. 사용 예제

clsx는 다양한 상황에서 활용될 수 있습니다.

  • 버튼 스타일 변경
  • 컴포넌트 상태에 따라 클래스 이름 변경
  • 테마에 따라 클래스 이름 변경
  • 조건부로 여러 클래스 적용

7. 결론

clsx는 React에서 클래스 이름을 조건부로 적용하는 데 매우 유용한 라이브러리입니다. 간결하고 효율적인 코드를 작성할 수 있도록 다양한 기능을 제공하며, TypeScript와 함께 사용하여 문법 오류를 감지할 수 있습니다.