오늘은 공통 컴포넌트 Chip을 개발해 보겠습니다.
// Chip.ts
import { ReactNode } from 'react';
type ChipType = 'tag' | 'status' | 'status-option';
export interface ChipProps {
children: ReactNode;
chipType: ChipType;
}
export const bgTag = ['orange', 'green', 'pink', 'blue'];
// Chip.tsx
import clsx from 'clsx';
import { ChipProps } from '@/type/chip';
import { PropsWithChildren } from 'react';
import styles from './Chip.module.css';
import getTagColor from './helper';
/**
* Chip 컴포넌트
* - 다양한 유형의 Chip을 렌더링하는 공통 컴포넌트.
* - chipType(['tag', 'status', 'status-option'])에 따라 스타일과 Dot 렌더링 여부를 결정합니다.
*
* @param {string} props.chipType - Chip의 타입을 지정
* @param {React.ReactNode} props.children - Chip 내부에 렌더링할 내용
* @returns {JSX.Element} Chip 컴포넌트의
*/
function Chip({ children, chipType }: PropsWithChildren<ChipProps>) {
/**
* renderDot: status인 타입인 경우 점을 렌더링
* - 조건: chipType.startsWith('status') -> status | status-option
* @returns {JSX.Element} - 점 span 태그
*/
const renderDot = () =>
chipType.startsWith('status') && <span className={styles.dot} />;
const className = clsx(
styles[chipType],
chipType === 'tag' && getTagColor(styles),
);
return (
<span className={className}>
{renderDot()}
{children}
</span>
);
}
export default Chip;
이번엔 아주 간단한 컴포넌트라 따로 파일을 분리할 필요가 없습니다.
그런데 한 가지만 문제가 생겼습니다. chipType이 'tag'인 경우 색상을 지정해줘야 한다는 것입니다.
할 일 생성 모달에서 태그 칸에 텍스트를 입력 후 엔터를 누르면 텍스트가 태그 형식으로 바뀌는 구조입니다.
그런데 태그가 특정 몇 개로 정의된 것도 아니고 태그마다 배경색을 지정해 줄 수 있는 방법이 없습니다.
오전 스크럼 때 팀원들에게 이슈를 공유하고 피그마에 정의된 4가지 색상 중 생성 시 랜덤하게 적용하는 방향으로 마무리되었습니다.
랜덤으로 색상 추가하는 로직
import { bgTag } from '@/type/chip';
/**
* 랜덤한 tag 클래스를 반환하는 함수
* - bgTag 배열에서 랜덤하게 선택
*
* @param {Record<string, string>} styles - 스타일 객체
* @returns {string} 랜덤 배경색 클래스 이름
*/
const getTagColor = (styles: Record<string, string>): string => {
if (!bgTag || bgTag.length === 0) return '';
const idx = Math.floor(Math.random() * bgTag.length);
return styles[bgTag[idx]];
};
export default getTagColor;
결과물
Chip 컴포넌트를 제작하고 멘토님께 한 가지 코드 리뷰를 받았습니다.
타입스크립트에서 JSDoc으로 주석을 작성하는 것이 불필요한 중복 작업일 수 있다는 것입니다.
그 외에도 다른 문제점들이 있을 것 같아서 추가로 검색해 보니 다음과 같은 문제점들이 있었습니다.
- 중복성 : 타입스크립트는 이미 자체적으로 타입을 정의할 수 있는 기능을 제공하는데, JSDoc을 사용하면 타입을 다시 주석 형식으로 작성해야 하므로 중복된 작업이 발생합니다. TypeScript에서 타입을 명시적으로 정의하는 것이 더 효율적일 수 있습니다.
- 오류 가능성 : JSDoc에서 잘못된 타입 주석을 작성하면, 타입 검사가 제대로 이루어지지 않아서 런타임 오류가 발생할 수 있습니다. TypeScript의 정적 타입 검사 시스템을 사용하는 것보다 오류를 추적하기 어려운 경우가 많습니다.
- 디버깅 어려움 : JSDoc에서 작성된 타입 정보는 TypeScript 컴파일러에 의해 실제 타입으로 변환되지 않기 때문에, 디버깅 시 타입 관련 문제를 추적하는 데 어려움이 있을 수 있습니다.
- 자동 완성 및 인텔리센스 제한 : TypeScript는 타입 정보를 활용하여 자동 완성 기능이나 코드 인텔리센스를 제공하지만, JSDoc으로 제공된 타입 정보는 TypeScript 타입 시스템만큼 완벽하게 인식되지 않아 자동 완성이 제한될 수 있습니다.
팀원들에게 제 코드를 쉽게 알아볼 수 있도록 작성한 주석이 오히려 타입스크립트의 고유 시스템을 완전히 활용하는데 방해가 된다니..
지금부터는 JSDoc을 사용하지 않고 코드 자체가 직관적이고 이해하기 쉽도록 작성해야겠습니다.
- 함수와 변수 이름을 명확하게 작성하기
- 의미가 명확한 이름을 사용하여 코드의 목적과 동작을 직관적으로 전달.
- 약어 사용을 지양하고, 가능하면 완전한 단어를 사용.
- 불필요한 복잡성 피하기
- 로직을 간결하게 작성해 이해하기 쉬운 코드를 작성.
- 중복 코드 제거 및 코드 간결화.
- 코드의 목적 명확하게 전달
- 함수나 변수의 역할을 분명히 하여 코드를 읽는 사람이 쉽게 이해할 수 있도록 작성.
- 함수 하나가 하나의 명확한 작업만 하도록 작성(단일 책임).
- 주석 최소화
- 코드 자체로 의도가 명확하게 전달되도록 작성해 주석을 최소화.
- 주석이 필요한 경우 중요한 부분에만 간결하게 작성.
- 가독성 유지
- 코드 블록 간 적절한 개행을 통해 일관된 스타일로 가독성을 높임.
- 코드 길이를 적절히 유지하여 한눈에 파악할 수 있도록 작성.
'프로젝트 > Next+TypeScript' 카테고리의 다른 글
[Taskify] 무한스크롤 - 해결 (4) | 2024.12.19 |
---|---|
[Taskify] 대시보드 상세 - 무한 스크롤 (4) | 2024.12.19 |
[Taskify] 대시보드 상세 페이지 (4) | 2024.12.17 |
[Taskify] 버튼(공통 컴포넌트) 추가 (4) | 2024.12.13 |
[프로젝트] Taskify (태스키파이) 소개 (5) | 2024.12.12 |