프로젝트의 컴포넌트를 만들 때 기존 태그의 props를 그대로 상속받아서 사용할 수 있게 만들어야 할 때가 있다.
리액트에서 제공하는 엘리먼트의 속성 타입들은 여러가지가 있다.
- HTMLAttributes
- [Element]HTMLAttributes<HTML[Element]Element>
- ComponentPropsWithRef
- ComponentPropsWithoutRef
HTMLAttributes
HTMLAttributes 는 key, ref 같은 props 타입이 정의되어있지 않기 때문에, 사용에 적합하지 않다.
[Element]HTMLAttributes<HTML[Element]Element>
type MyButtonProps = {
backgroundColor?: string;
} & ButtonHTMLAttributes<HTMLButtonElement>;
const MyButton = (props: MyButtonProps) => {
return <button {...props}></button>;
};
해당 타입은 위와같이 적용할 수 있다.
하지만 타입의 네이밍이 직관적이지 않다.
분명 ButtonHTMLAttrubutes 인데 제네릭으로 HTMLButtonElement 을 넣어줘야 하다니..?
ComponentPropsWithoutRef
type MyButtonProps = {
backgroundColor?: string;
} & ComponentPropsWithoutRef<'button'>;
const MyButton = (props: MyButtonProps) => {
return <button {...props}></button>;
};
해당 타입은 제네릭으로 HTML 태그를 받는다.
그래서 사용할 때 통일성있고 직관적이다.
그리고 내부적으로는 [Element]HTMLAttributes 이용하고 있다.
ref를 받아야 할 경우는?
ref를 받아야할 때는 forwardRef로 컴포넌트를 감싸줘야한다
type MyButtonProps = {
backgroundColor?: string;
} & ComponentPropsWithoutRef<'button'>;
export const MyButton = forwardRef((props: MyButtonProps, ref: Ref<HTMLButtonElement>) => {
return <button {...props}></button>;
});
ComponentPropsWithRef 라는 타입도 제공해주지만, ref를 받기 위해서는 forwardRef로 감싸는게 필수적이기 때문에, 사용할 이유가 좀 떨어진다.
오히려 ref를 받지 않는데 ComponentPropsWithRef 를 선언한다면 해당 컴포넌트를 사용하는 쪽에서 ref 를 추론하기 때문에 혼란스러울 수 있다.
따라서 결론은 ComponentPropsWithoutRef 이용을 추천한다.
타입 선언을 더 자세하게 알고 싶다면 @types/react를 살펴보자
'프론트엔드' 카테고리의 다른 글
[번들 사이즈 최적화] 웹팩으로 생성한 번들 파일을 분석해보자(BundleAnalyzerPlugin) (0) | 2023.09.11 |
---|---|
회원가입 폼에서 주로 쓰이는 필수입력사항에* 별표 표시하기 (0) | 2023.07.16 |
KDC 한국십진분류표 (0) | 2023.06.21 |
styled-components를 이용할 때 기존 태그의 attributes를 override하는법 (0) | 2023.06.20 |
typescript로 상수와 타입을 선언하는 방법: as const, enum (0) | 2023.06.16 |