[React Dot Notation] 리액트 컴포넌트 점 표기법
왜 이런 방법을 찾아봤을까?
이번에 현재 회사로 이직하면서 디자인 시스템을 만들고 싶다는 디자이너 분과 함께 일하게 되었다. 그분은 이미 다 갖춰진 대기업에서 디자이너로 일하셨었고 실무는 많이 안 해보셨다. 전에 있던 개발자가 모든 페이지마다 컴포넌트를 따로 만들어서 개발했다고 하시며, 그렇게 안 하면 좋겠다는 의사를 보이셨다.
그래서 미리 컴포넌트를 정의하고 그걸 여러 군데에서 사용하면 좋겠다고 했는데, 결국 디자인 시스템을 만드는 방향으로 갔다. 나 역시 동의했고 앞으로 계속 진행될 신규 프로젝트나 레거시 프로젝트 리뉴얼 등 많은 곧에서 재사용되며 우리 회사의 브랜딩을 일관화하며 개발 속도까지 높일 수 있다고 판단했기 때문이다.
여튼 그래서 피그마에 여러 컴포넌트들이 정의되었고, 나는 그것을 기반으로 디자인 시스템을 바탕으로 한 UI 라이브러리를 만들려고 했다. 피그마를 써본 사람들은 알겠지만, 피그마에 정의된 컴포넌트를 내부에서 사용할 수 있다. 그리고 그 컴포넌트를 클릭해보면 오른쪽 화면에는 아래와 같이 나오기 때문에 어떤 컴포넌트를 사용했지는지 쉽게 알 수 있다.
그럼 이제 개발자가 사용하게될 UI 라이브러리를 만들게 되는데 나는 고민이 생겼다. (여러 컴포넌트가 있겠지만, 설명의 편의를 위해 대표적으로 Typography에 대해서만 예제로 삼겠다.) SubHeadline1, SubHeadline2, SubHeadline3, ..., Pargraph1, Pargraph2,..., Caption1, Caption2... 이런 식으로 정의해 놓으면 이 라이브러리를 사용하는 사용자(개발자)가 과연 편할까? 다 같은 Typography인데 하나로 묶을 순 없을까? 이렇게 내가 사용했던적이 있나?
그래서 material-ui를 한번 참고해 봤다.
<Typography variant="h1" gutterBottom>
h1. Heading
</Typography>
<Typography variant="h2" gutterBottom>
h2. Heading
</Typography>
이걸 내가 만드는 UI라이브러리에 적용한다면?
<Typography variant="SubHeadline1" gutterBottom>
h1. Heading
</Typography>
<Typography variant="SubHeadline3" gutterBottom>
h2. Heading
</Typography>
음 아주 별로였다. 스펠링 틀리면? 타입스크립트라 타입 체크해 주면 자동완성 기능으로 입력해도 된다? 뭔가 만족스럽지 못한 결론에 계속 도달했다.
저기서 좀 더 발전시켜서 variant를 enum으로 받으면 어떨까?
<Typography variant={TypoVariant.SubHeadline1} gutterBottom>
h1. Heading
</Typography>
<Typography variant={TypoVariant.SubHeadline3} gutterBottom>
h2. Heading
</Typography>
// -------------
export enum TypoVariant {
SubHeadline1 = 'SubHeadline1',
SubHeadline2 = 'SubHeadline2',
...
}
이 방법 또한 유쾌한 방법같진 않았다. 이것을 사용하는 개발자가 스토리북이건 어떠한 Documents를 참고해서 TypoVariant라는 enum 값을 알아야 한다는 거 자체가 마음에 들지 않았다. 특히 Typography의 경우 사용 빈도도 높기 때문에 더 쉽고 간단한 방법을 찾고 싶었다. 그래서 찾은 방법이 [Dot Notation]이었다.
Dot Notation
// Dot Notation
<MyComponents.DatePicker color="blue" />
React 공식 문서에서도 스치듯 나오는 내용이다.
많은 리액트 컴포넌트를 내보낼때 유용하다고? 이거 딱인데?
적절한 대안을 발견했다. 컴포넌트를 정의하는 방법 또한 간단했다. 내가 원하는 컴포넌트를 적절한 키값과 객체의 값으로만 넣어주면 되었다. Typography가 갖는 공통된 인터페이스를 정의(fontWeight, color, size,...)하였고, Typography는 사용빈도도 많지만 너무 길다고 판단되어 "Typo"라는 객체로 추상화하기로 했다.
개발시에 <Typo. 까지만 입력하면 자동완성으로 내가 그룹핑한 컴포넌트가 모두 나오기 때문에 개발자가 사용하기도 편하고, 피그마에 정의된 이름을 모두 그대로 가져갔기 때문에 개발과 디자인 시스템의 괴리도 전혀 없다. 실제 개발시에 사용해도 전혀 불편함 없이 사용하고 있는 중이다.
나는 아래와 같이 코드를 작성했다. 공식 홈페에지에 있는 예제처럼 작성해도 되고, 내가 구현한 것처럼 작성해도 문제없다. 개인의 취향과 학습의 정도에 따라 맞는 걸로 선택하면 될 거 같다!
import React, { FC } from "react";
import * as Headline from "./Headline";
import * as Pargraph from "./Pargraph";
export const Typo: FC & Headline.HeadlineType & Pargraph.PargraphType = ({
children
}) => {
return <>{children}</>;
};
Typo.Headline1 = Headline.Headline1;
Typo.Pargraph1 = Pargraph.Pargraph1;
예제 코드)