조건부로 className을 결합하는 간단한 JavaScript 유틸리티입니다. classnames 홈페이지
React의 경우 view에 집중한 라이브러리인 만큼 조건부로 CSS 클래스를 추가하거나 제거해야 하는 경우가 많습니다. 이럴 때 classnames를 사용하면 조건부로 CSS 클래스를 추가할 때 매우 편리합니다.
npm install classnames
classNames는 문자열이나 객체가 될 수 있는 인수를 원하는 만큼 넣을 수 있습니다. 특정 키와 연결된 값이 거짓인 경우 해당 키는 출력되지 않습니다.
classNames('foo', 'bar'); // => 'foo bar' classNames('foo', { bar: true }); // => 'foo bar' classNames({ 'foo-bar': true }); // => 'foo-bar' classNames({ 'foo-bar': false }); // => '' classNames({ foo: true }, { bar: true }); // => 'foo bar' classNames({ foo: true, bar: true }); // => 'foo bar' classNames('foo', { bar: true, duck: false }, 'baz', { quux: true }); // => 'foo bar baz quux' classNames(null, false, 'bar', undefined, 0, { baz: null }, ''); // => 'bar' }
import React, { useState } from 'react'; export default function Button (props) { const [isPressed, setIsPressed] = useState(false); const [isHovered, setIsHovered] = useState(false); // 조건문을 통해 CSS를 관리하고 있습니다. let btnClass = 'btn'; if (isPressed) btnClass += ' btn-pressed'; else if (isHovered) btnClass += ' btn-over'; return ( <button className={btnClass} onMouseDown={() => setIsPressed(true)} onMouseUp={() => setIsPressed(false)} onMouseEnter={() => setIsHovered(true)} onMouseLeave={() => setIsHovered(false)} {props.label} </button> ); }
import React, { useState } from 'react'; import classNames from 'classnames'; export default function Button (props) { const [isPressed, setIsPressed] = useState(false); const [isHovered, setIsHovered] = useState(false); // classNames를 통해 조건부 CSS를 객체로 더 간단하게 표현합니다. const btnClass = classNames({ btn: true, 'btn-pressed': isPressed, 'btn-over': !isPressed && isHovered, }); return ( <button className={btnClass} onMouseDown={() => setIsPressed(true)} onMouseUp={() => setIsPressed(false)} onMouseEnter={() => setIsHovered(true)} onMouseLeave={() => setIsHovered(false)} {props.label} </button> ); }
이를 사용하면 클래스 중복을 올바르게 제거할 수 있습니다. 또한 두 번째 인수로 전달된 객체에서 값이 거짓인 키는 결과에서 제외됩니다.
const classNames = require('classnames/dedupe'); console.log(classNames('foo', 'foo', 'bar')); // => 'foo bar' console.log(classNames('foo', { foo: false, bar: true })); // => 'bar'
- classNames('foo', 'foo', 'bar')를 호출하면 'foo' 클래스가 중복되므로 중복이 제거되고 'foo bar' 문자열이 반환
- { foo: false, bar: true } 객체를 전달하면 foo 키의 값이 거짓이므로 'foo' 클래스가 결과에서 제외되고 'bar' 클래스만 남고,'bar' 문자열이 반환
classNames는 bind 버전을 통해 css-modules하고도 같이 사용할 수 있습니다.