데브코스/도서 판매 쇼핑몰

[FE] 기본 컴포넌트 작성(Title, Button, Input)

hxx_1 2024. 11. 13. 22:56

Title 컴포넌트

① 인터페이스 정의 

interface Props {
  children: React.ReactNode;  // 타이틀 내용
  size: HeadingSize;         // 제목 크기
  color?: ColorKey;          // 선택적 색상 값
}
  • HeadingSize와 ColorKey는 theme 파일에서 정의된 타입을 사용한다.

② 컴포넌트 구현

function Title({ children, size, color }: Props) {
  return (
    <TitleStyle size={size} color={color}>
      {children}
    </TitleStyle>
  );
}

 

③ 스타일 구현

const TitleStyle = styled.h1<Omit<Props, "children">>`
  font-size: ${({ theme, size }) => theme.heading[size].fontSize};
  color: ${({ theme, color }) =>
    (color ? theme.color[color] : theme.color.primary)};
`;
  • Omit<Props, "children">을 사용하여 Props에서 children을 제외한 타입을 스타일 컴포넌트에 적용한다.

 

Button 컴포넌트

 

① 인터페이스 정의

interface Props {
  children: React.ReactNode;  // 버튼 내용
  size: ButtonSize;          // 버튼 크기
  scheme: ButtonScheme;      // 버튼 색상 스키마
  disabled?: boolean;        // 비활성화 상태
  isLoading?: boolean;       // 로딩 상태
}
  • size prop에 따라 폰트 크기와 패딩이 조절된다.
  • scheme prop에 따라 텍스트 색상과 배경색이 변경된다.
  • disabled 상태에 따라 투명도와 상호작용이 조절된다.

② 컴포넌트 구현

function Button({ children, size, scheme, disabled, isLoading }: Props) {
  return (
    <ButtonStyle
      size={size}
      scheme={scheme}
      disabled={disabled}
      isLoading={isLoading}
    >
      {children}
    </ButtonStyle>
  );
}

 

Input 컴포넌트

① 인터페이스 정의

interface Props {
  placeholder?: string;  // 선택적 플레이스홀더 텍스트
}

 

② 컴포넌트 구현

const InputText = React.forwardRef(({placeholder}: Props, ref: ForwardedRef<HTMLInputElement>) => {
  return (
    <InputTextStyled placeholder={placeholder} ref={ref} />
  )
})
  • React.forwardRef를 사용하여 상위 컴포넌트에서 입력 요소에 직접 접근할 수 있다.
  • ForwardedRef<HTMLInputElement> 타입을 사용하여 타입 안정성을 보장한다.

③ 스타일 구현

const InputTextStyled = styled.input.attrs({type: "text"})`
  padding: 0.25rem 0.75rem;
  border: 1px solid ${({theme}) => theme.color.border};
  border-radius: ${({theme}) => theme.borderRadius.default};
  font-size: 1rem;
  line-height: 1.5;
  color: ${({theme}) => theme.color.text};
`;
  • attrs 메서드를 사용하여 input 타입을 "text"로 고정한다.
  • 이는 불필요한 prop 전달을 방지하고 일관된 입력 타입을 보장한다.

🌟 배운 점

오늘 기본 컴포넌트를 작성했으나 타입스크립트 문법에 아직 익숙하지 않아 코드를 이해하는 데 다소 어려움이 있었다. 또한, styled-components를 사용하는 것이 기존의 CSS 파일을 사용하는 것보다 어떤 장점이 있는지 궁금해 찾아보니, 첫째로 동적 스타일링이 용이하고, 오늘 작성한 컴포넌트처럼 테마 시스템을 활용할 수 있다는 점이 있었다. 또한, 컴포넌트 확장이 쉬우며 자바스크립트 로직을 활용할 수 있어 리액트에서 많이 사용된다고 한다. 앞으로 styled-components를 많이 사용해 보면서 이러한 장점을 체감해봐야겠다.