기본 HTML 요소를 확장하는 TypeScript에서 React UIKIT 구성 요소를 만드는 방법

프런트 엔드 에코시스템에서 UiKits는 다음과 같은 유틸리티 및 여러 구성 요소의 모음입니다.
  • <Card />
  • <TabBar />
  • <Carousel />
  • <Row /><Col />
  • <GoogleMap />

  • 각 구성 요소에는 일반적으로 고유한 사용자 지정 레이아웃이 있으며 여러 속성을 허용할 수 있습니다. 예를 들어 <GoogleMap /> 구성 요소는 "coordinates"및 "zoom"값을 속성으로 허용할 수 있습니다.

    <GoogleMap coords={coords} zoom={zoom} />
    


    레이아웃이 처음부터 생성된 구성 요소를 만들어야 하는 경우가 있습니다. 다른 경우 레이아웃은 기본 요소를 기반으로 할 수 있습니다.
    몇 가지 예:
  • <MyButton /> : <button> 요소 기능 확장
  • <MyImg /> : 확장<img> 요소
  • 등등.

  • 아래 코드로 사용할 수 있는 레이블 옆에 아이콘을 표시해야 하는 button 구성 요소를 상상해 봅시다.

    <MyButton icon="💩"> CLICK ME </MyButton>
    


    이 구성 요소는 iconchildren 속성을 허용해야 하며 해당 정의는 다음과 같습니다.

    interface MyButtonProps {
      icon: string;
    }
    
    function MyButton(props: PropsWithChildren<MyButtonProps>) {
      const { icon, children } = props;
      return <button className="btn btn-primary">
        {icon} {children}
      </button>
    }
    


    따라서 다음과 같이 구성 요소를 사용할 수 있습니다.

    <MyButton icon="💩"> DO SOMETHING</icon>
    <MyButton icon="😱"> CLICK ME</icon>
    





    유연성을 높이려면 <MyButton /> 구성 요소도 모든 기본button 속성을 수락해야 합니다. 예를 들어 onClick 이벤트를 수신하거나 disabled 속성을 설정해야 할 수 있습니다.

    <MyButton icon="💩" onClick={() => {}} disabled />
    


    따라서 구성 요소의 속성 유형에 간단히 추가하고 <button> 요소의 특성으로 적용할 수 있습니다.

    // 1. Add the properties 
    interface MyButtonProps {
      icon: string;  
      disabled: boolean;   // ➡️ native prop
      onClick: (e: React.MouseEvent) => void; // ➡️ native prop
      // ➡️ other native props
    }
    
    function MyButton(props: PropsWithChildren<MyButtonProps) {
    
      const { icon, children, onClick, disabled } = props;
      // 2. apply all props one by one
      return <button disabled={disabled} onClick={onClick} className="btn btn-primary">
        {icon}
        {children}
      </button>
    }
    


    기본 버튼의 모든 속성을 수동으로 전달하지 않으려면 어떻게 해야 합니까?

    트릭이 있습니다!

    intersection type을 사용하여 사용자 지정 소품을 모든 HTMLButtonElement 속성과 결합하여 모든 기본 버튼 속성을 자동으로 지원할 수 있습니다.

    export function MyButton(
      props: PropsWithChildren<MyButtonProps & React.ButtonHTMLAttributes<HTMLButtonElement>>
    ) { 
     // ... component here ...
    }
    


    이제 구성 요소가 모든 버튼 속성을 지원하고 다음 트릭을 사용하여 간단하게 적용할 수 있습니다.

    // apply all props as button attributes
    return <button className="btn btn-primary" {...props}>
    


    그러나 iconchildren는 유효한 버튼 속성이 아니므로 destructuring을 사용하여 이를 제외한 모든 속성을 포함하는 rest 속성을 만들 수 있습니다.

      const { icon, children, ...rest } = props;
    
      // Now we apply all props except icons and children
      return <button className="btn btn-primary" {...rest}>
        {icon}
        {children}
      </button>
    


    그리고 그게 다야.
    다음은 icon , children 및 모든 기본 버튼 속성을 지원하는 버튼을 만드는 최종 소스 코드입니다.

    import { PropsWithChildren } from 'react';
    
    interface MyButtonProps {
      icon: string;
    }
    export function MyButton(
      props: PropsWithChildren<MyButtonProps & React.ButtonHTMLAttributes<HTMLButtonElement>>
    ) {
      const { icon, children, ...rest } = props;
      return <button className="btn btn-primary" {...rest}>
        {icon}
        {children}
      </button>
    }
    
    


    사용 예:




    <MyButton 
      icon="💩" 
      type="submit"
      disabled={...} 
      onClick={...} 
      onMouseOver={...} 
    > CLICK ME </MyButton>
    



    이 기사를 읽을 수도 있습니다.



    🔗 나를 팔로우하세요:


  • Twitch
  • Twitter
  • 좋은 웹페이지 즐겨찾기