React의 className
리액트는 JSX문법에 따라 class가 아닌 className을 통해 element의 클래스를 지정해준다. 그런데 클래스명을 지정해주다 보면 불필요하게 코드가 길어지거나 일관성이 떨어지는 등의 문제가 발생하기도 한다.
첫 번째 예시를 보자. 여러 클래스명이 존재할 때 클래스명은 서로 공백을 통해 구분된다. 만약 경우에 따라 클래스명이 추가될 수도 추가되지 않을 수도 있을 때 이것은 매우 귀찮은 문제를 만든다. 클래스명이 추가될지 여부도 모르는 채 공백을 추가해줘야 하며 어떠한 방식으로 표현해도 관련 코드가 보기 안 좋아진다. (공백 처리 관련하여 join을 활용한 classNameGenerator 함수를 만들어줘도 되지만 그 역시 효율적이라고 볼 수는 없다.)
두 번째 예시이다. object를 클래스명을 관리할 경우 대부분의 경우에 object.property와 같이 dot notation으로 클래스명에 접근할 것이다. 꼭 클래스명이 아니더라도 object의 property에 접근할 때는 대부분 dot notation을 활용할 것이다. 그것이 코드도 짧고 가독성도 좋다. object를 클래스명으로 관리한다는 것이 무슨 이야기인지 바로 감이 잡히지 않을 수도 있는데 css module을 생각하면 바로 무슨 이야기인지 이해가 될 것이다.
그런데 클래스명은 특히나 dot notation만으로 사용하기에는 무리가 있는 방법이다. 클래스명에는 하이픈, 혹은 더블 하이픈이 들어갈 수 있다. ('-', '--') 이 경우 dot notation을 사용할 수 없으며 두 번째 방법인 bracket notation을 활용해야 한다. bracket notation은 object['property name']과 같은 방법으로 object property에 접근하는 방법을 의미한다. dot notation보다 직관성은 부족하지만 중간에 공백, 하이픈 등이 포함된 경우에도 대처할 수 있다는 점에서 장점을 가진다. 다시 본론으로 돌아왔을 때 우리는 두 가지 선택지에 놓인다. 모든 클래스명을 bracket notation으로 접근하거나, dot notation을 일반적으로 사용하되 예외의 경우에만 bracket notation을 사용하거나. 전자의 경우에는 가독성이 부족하며 코드의 길이도 조금씩 길어진다. 또한 dot notation을 사람들이 선호하는 것도 무시할 수 없다. 후자의 경우 코드의 일관성이 떨어지게 된다. 코드의 일관성 역시 가독성과 직결되는 요소이기 때문에 결코 무시할 수 없다.
classnames 라이브러리
이러한 문제들을 간단하게 해결할 수 있게 해주는 것이 바로 classnames 라이브러리이다. classnames의 사용 방법은 다음과 같다.
(1) 원하는 클래스명들을 모두 인자로 전달한다.
(2) optional classname을 지정해주고 싶다면 클래스명을 프로퍼티명으로, 포함 여부를 value로 가지는 object를 넣어주면 된다. 만약 value가 true인 경우 해당 클래스명은 포함되며 false인 경우 해당 클래스명은 포함되지 않는다. value는 자동적으로 boolean처리 되기 때문에 !! 연산자 등을 활용하여 강제로 boolean값으로 변경해줄 필요는 없다. (실제로 지양하는 방법이기도 하다.) 추가로 한 object 내에 여러 클래스명을 넣어줄 수도 있다.
(3) 불필요한 값들은 클래스명으로 적용되지 않는다. 예를 들어서 undefined, null, false, 0, '' 등의 값은 모두 무시된다.
(4) 만약 css module과 함께 사용해주고 싶다면 classnames 라이브러리의 bind를 활용하면 된다. 예를 들어서 두 번째 예시에서 제시한 Logo 컴포넌트에 classnames의 bind를 적용하면 다음과 같은 코드가 된다. 그 전 코드보다 일관성이 향상된 것을 볼 수 있다. (참고로 cx라는 이름을 사용한 것은 공식 문서를 보고 그대로 적용한 것이다. 왜 이러한 이름을 적용했나 확인해봤는데 과거 리액트에서 classNames보다 제한적인 기능을 가진 classSet이라는 기능을 기본적으로 제공했는데 이 때 사용하던 cx라는 이름이 그대로 굳혀진 것이라고 한다. 하지만 cx라는 이름 자체의 의미는 아직 확실히 모르겠다. 참고 링크)
'프론트엔드 기본개념 복습 > React' 카테고리의 다른 글
[React] react-query에서 에러 처리하기 (0) | 2022.04.23 |
---|---|
[React] React Hook Form으로 간단하게 리액트에서 폼 사용하기 (0) | 2022.04.18 |
[React] useLayoutEffect vs useEffect (0) | 2022.04.11 |
[React Native] React Native의 작동 원리 (0) | 2022.03.10 |
[React] 리액트 최적화하기 (Optimization in React) (0) | 2022.03.10 |