프로젝트/Next+TypeScript

[Taskify] Chip(공통 컴포넌트) 추가

dev-hpk 2024. 12. 16. 21:48

공통 Chip 컴포넌트 UI

 

오늘은 공통 컴포넌트 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을 사용하지 않고 코드 자체가 직관적이고 이해하기 쉽도록 작성해야겠습니다.

  • 함수와 변수 이름을 명확하게 작성하기
    • 의미가 명확한 이름을 사용하여 코드의 목적과 동작을 직관적으로 전달.
    • 약어 사용을 지양하고, 가능하면 완전한 단어를 사용.
  • 불필요한 복잡성 피하기
    • 로직을 간결하게 작성해 이해하기 쉬운 코드를 작성.
    • 중복 코드 제거 및 코드 간결화.
  • 코드의 목적 명확하게 전달
    • 함수나 변수의 역할을 분명히 하여 코드를 읽는 사람이 쉽게 이해할 수 있도록 작성.
    • 함수 하나가 하나의 명확한 작업만 하도록 작성(단일 책임).
  • 주석 최소화
    • 코드 자체로 의도가 명확하게 전달되도록 작성해 주석을 최소화.
    • 주석이 필요한 경우 중요한 부분에만 간결하게 작성.
  • 가독성 유지
    • 코드 블록 간 적절한 개행을 통해 일관된 스타일로 가독성을 높임.
    • 코드 길이를 적절히 유지하여 한눈에 파악할 수 있도록 작성.

 

 

[Taskify] 버튼(공통 컴포넌트) 추가

프로젝트에서 공통으로 사용하는 버튼 컴포넌트 개발을 맡게 되었습니다.아래 보이는 버튼들을 모두 하나의 버튼 컴포넌트로 관리해야 한다니... 일단 도전!// Button.tsximport styles from "./Button.module

dev-hpk.tistory.com

 

 

[프로젝트] Taskify (태스키파이) 소개

드디어 중급 프로젝트 시작이다!! 지난 초급 프로젝트는 팀원들 모두 첫 프로젝트를 진행하는 상황이라 소통과 일정 관리, 그리고 업무 분담 면에서 많은 어려움이 있었습니다. 작업이 겹치거

dev-hpk.tistory.com