React 클래스이름이 적용된 컴폰너트 만드는 로직

2019.12.02 06:20

x

저는 프론트엔드를 개발할때 CSS규칙이 좀 특이합니다. 일반적으로 CSS를 작성하신다면 *를 이용하거나 각 태그들을 모두 같은 스타일로 초기화하고 사용하는실겁니다.

그러나 저는 각 태그별로 사용하는 CSS만 초기화하는 방식으로 사용합니다. 그러면서 한가지 습관이 들여진게 있는데 바로, 클래스이름을 해당 태그의 이름을 넣고 시작하는겁니다.

예를들면 리액트 컴포넌트로 생각을 한다면, Button이라는 <button class="button"></button>을 렌더링하는 컴포넌트를 만들고 시작합니다.
사용을한다면, <Button onClick={...}>확인</Button>으로 이름이 카멜케이스인 컴포넌트를 사용하게 되는것이죠.

이 방식에는 장점이 있습니다. 스타일을 적용한 컴포넌트와 스타일이 없는 순수 태그를 모두 사용이 가능하다는 점이있고, 외부 CSS보다 충돌이 많이 적은 편이라는것이죠.

외부 라이브러리에 대해 좀 얘기하면, 아마 많은 분들이 Bootstrap이나 기타 다른 CSS 스타일 라이브러리를 사용해보신다면 겪어보셨을 겁니다. 버튼 스타일 하나 바꿀려고 그 라이브러리의 내부를 뜯어보거나 브라우저 개발자 도구를 열어서 하나 하나 확인한적 있으실겁니다. 그 라이브러리가 어떤 스타일을 적용해놨는지도 모르니 말이죠.

저는 두가지 장점 때문에 직접 스타일을 하나 하나 짜가는 습관을 들여놨습니다. 아직 협업에선 초짜인지라 그런상황이 된다면 이게 득이될지 실에될지에 대해서는 차차 확인해 나가면서 제 습관을 고쳐야할 수도 있다는 점이있지만요.

쨌든, 이런방식의 습관을 쫌더 쉽게사용하려고 Classed라는 리액트에서 사용할 컴포넌트를 만들어주는 함수를 만들었습니다. 오늘은 이것을 소개할 겁니다.

알아야할것들

React컴포넌트인 만큼 React를 아셔야합니다. Jsx의 구조까진 아니더라도, React의 createElementforwardRef함수를 아신다면 아주 편해질겁니다. 그리고 저는 최신버전의 React를 사용하다보니 함수형 컴포넌트를 주로 사용하고, Hooks를 같이 사용합니다.

그리고 저는 Typescript를 사용합니다. 자바스크립트랑 동일하나 타입만 추가적으로 작성해주는 언어이니 기존 자바스크립트를 사용하시는 분들은 그 부분들을 생략하시고 보시면됩니다.

사용할 커스텀 Hooks

useClassName

import React from 'react'; export const useClassName = (...classes: any[]) => { return React.useMemo(() => { return classes.filter(Boolean).join(' '); }, [classes]); };
typescript

이 커스텀 훅은 아주 간단합니다. 매개변수로 클래스 이름을 던져주면 띄어쓰기를 넣어 일반 브라우저에서 사용하는 클래스이름으로 구분해주는 간단한 훅입니다.

ex) useClassName('button', 'flat')을 사용하면 button flat을 주는 녀석입니다.

추가한 커스텀 Types

image
이 예제에서는 Typescript를 사용하는 만큼 이런 유틸 타입을 안만들어 놓으면 타입만 만지작거리다 하루를 보낼 수 있어서 미리 만들어 놨습니다.
아마 생소한 타입들밖에 없을겁니다. 대부분 React가 제공하지만 JSX 컴파일러쪽에서 사용하는 타입들이거든요.

PropsOfComponent

컴포넌트의 Props의 타입을 추출하는 유틸 타입입니다. 이건 이 예제에서만 사용하기엔 아까운 아주 좋은 유틸타입입니다.

Element

이건 태그이름을 넣으면 각 HTMLElement타입으로 리턴해주는 녀석입니다. 이번 예제에서 많은것을 줄여줄 녀석입니다.

ElementProps

기본 태그들은 위의 PropsOfComponent를 사용 못합니다. 이건 React에서 추출해온것이예요...

Classed 함수

image
image
총 두가지 함수를 만들었습니다.
ClassedRefReact.forwardRef를 이용해 기본 태그를 덮은 컴포넌트지만, React의 기본 Ref를 사용해주도록 도와주기위한 녀석입니다.

Classed는 별도로 만들어진 컴포넌트에 className 속성으로 추가할때 사용하는 녀석입니다.

예제

image
간단한 예제입니다.

input에 값을 입력하고 버튼을 누르면 콘솔에 내용이 출력되는 예제입니다.

프로그래머의 재량이나 코딩 스타일에 따라 이 Classed함수는 쓸모가 있을 수 있고, 없을 수도 있습니다. 그러나 리액트의 내부 타입들을 살펴 볼 수있는 좋은 기회였습니다.