.
.
.
클래스 컴포넌트가 상속받는 React.Component와 React.PureComponent의 타입 정의
interface Component<P = {}, S = {}, SS = any> extends ComponentLifecycle<P, S, SS> {}
class Component <P, S> {
/*생략*/
}
class PureComponent<P = {}, S = {}, SS = any> extends Component<P, S, SS> {}
P : props
S : state ( 상태 )
-> Props와 state 타입을 제네릭으로 받고 있다.
React.FC 혹은 React.VFC로 타입 지정
FC : Function Component
React.FC와 React.VFC는 리액트에서 함수 컴포너느의 타입 지정을 위해 제공되는 타입
React.FC 먼저 등장 -> @types/react 16.9버번 : React.VFC 추가
React. FC : 암묵적ㅇ로 children 포함
-> 해당 컴포넌트에서 children을 사용하지 않더라도 children props를 허용.
children props가 필요하지 않은 컴포넌트에서는 . 더정확한 타입 지정을 하기 우해 React.FC보다 React.VFC를 많이 사용
React.VFC가 리액트 18버전으로 넘어오면서 삭제되고, React.FC에서 children이 사라졌음.
근데 최근에 나온 19버전에서 달라진 점은 ? (개인적으로 찾아봄)
: 타입스크립트 지원 강화
React 19는 타입스크립트와의 통합을 더욱 강화.
React.FC가 children을 기본 포함하지 않는 점이 유지되며, 명시적으로 children 타입을 추가해야 하는 점이 동일함.( 결론 : 동일 )
타입 정의
interface Props {
title: string;
children?: React.ReactNode;
}
const MyComponent: React.FC<Props> = ({ title, children }) => (
<div>
<h1>{title}</h1>
{children}
</div>
);
type PropsWithChildren<P> = P & { children?: ReactNode | undefined };
가장 보편적인 children 타입 : ReactNode | undefined
ReactNode : 여러 타입 포함, 더 구체적으로 타이핑하는 용도에는 적합 x
( ex. 특정 문자열만 허용하고 싶을 때 : children에 대해 추가로 타이핑해줘야 함. )
리액트는 실제 DOM x -> 가상의 DOM 기반 렌더링 ... 가상 DOM의 엘리먼트 : React ReactElement 형태로 저장.
즉, React ReactElement 타입은 리액트 컴포넌트를 객체 형태로 저장하기 위한 포맷...
React 엘리먼트(React Element)
: React에서 UI를 구성하는 가장 작은 단위.
: HTML 태그나 컴포넌트의 구조를 표현하는 객체(Object)
JSX.Element 타입 : 리액트의 ReactElement를 확장하고 있는 타입.
글로벌 네임스페이스에 정의되어 있어 외부 라이브러리에서 컴포넌트 타입을 재정의할 수 있는 유연성을 제공.->컴포넌트 타입을 재정의하거나 변경하는 것이 용이해짐.
글로벌 네임스페이스
: 프로그래밍에서 식별자(변수, 함수, 타입 등)가 정의되는 전역적인 범위.
즉, 어떠한 파일이든지 해당 스코프에서 선언된 식별자는 모든 곳에서 접근할 수 있음.
1) ReactElement
리액트 엘리먼트를 생성하는 createElement 메서드
: JSX가 createElement 메서드를 호출하기 위한 문법
JSX : 자바스크립트의 확장 문법. 리액트에서 UI를 표현하는 데 사용됨.
즉, JSX는 리액트 엘리먼트를 생성하기 위한 문법이며 트랜스파일러는 JSX 문법을 createElement 메서드 호출문으로 변환하여 리액트 엘리먼트를 생성함.
리액트는 이런 식으로 만들어진 리액트 엘리먼트 객체를 읽어서 DOM을 구성.
즉, ReactElement타입은 JSX의 createElement메서드 호출로 생성된 리액트 엘리먼트를 나타내는 타입.
2) ReactNode
ReactChild 타입 : ReactElement | string | number로 정의 -> ReactElement보다는 넒은 범위를 갖고 있음.
ReactNode는 ReactChild + boolean + null + undefined 등 훨씬 넓은 범주의 타입을 포함.
즉, ReactNode는 리액트의 render함수가 반환할 수 있는 모든 형태를 담고 있음.
3) JSXElement
: ReactElement의 제네릭
즉, JSXElement는 ReactElement의 특정 타입으로 props와 타입 필드를 any로 가지는 타입.
1) DetailedHTMLProps와 ComponentWithoutRef : HTML 태그의 속성 타입 활용
type NativeButtonProps = React.DetailedHTMLProps<
React.ButtonHTMLAttribute<HTMLButtonELement>,
HTMLButtonElement>;
type ButtonProps = {
onClick?: NativeButtonType["onClick"];
};
```tsx
// HTML 버튼 속성의 타입을 정의합니다.
// React.DetailedHTMLProps: React에서 제공하는 HTML 속성 정의 유틸리티입니다.
// React.ButtonHTMLAttributes<HTMLButtonElement>: HTML 버튼 요소의 모든 속성을 포함합니다.
// HTMLButtonElement: 실제 DOM 버튼 요소 타입을 명시합니다.
type NativeButtonProps = React.DetailedHTMLProps<
React.ButtonHTMLAttributes<HTMLButtonElement>,
HTMLButtonElement
>;
// 사용자 정의 버튼 속성을 정의합니다.
// onClick 속성만 포함하며, NativeButtonProps에서 onClick 속성의 타입을 참조합니다.
type ButtonProps = {
onClick?: NativeButtonProps["onClick"]; // HTML 버튼 요소의 onClick 속성 타입과 동일
};
// 버튼 컴포넌트 정의
const CustomButton: React.FC<ButtonProps> = ({ onClick }) => {
return (
// 버튼 요소 정의
// onClick 핸들러를 받아 버튼 클릭 시 실행됩니다.
<button onClick={onClick} className="custom-style">
클릭
</button>
);
};
// 버튼 컴포넌트를 기본 내보내기
export default CustomButton;
: ButtonProps의 onClick 타입은 실제 HTML button 태그의 onClick 이벤트 핸들러 타입과 동일하게 할당되는 것을 확인 가능
type NativeButtonType = React.ComponentPropsWithoutRef<"button">;
type ButtonProps = {
onClick?: NativeButtonType["onClick"];
};
: 마찬가지로 button onClick 이벤트 핸들러 타입과 동일하게 할당되는 것을 확인 가능
2) 언제 ComponentPropsWithoutRef를 사용하면 좋을까
ref
: 생성된 DOM 노드나 리액트 엘리먼트에 접근하는 방법
ComponentPropsWithoutRef
는 특정 React 컴포넌트 타입의 props를 가져오되, ref
속성을 제외한 타입을 사용하고 싶을 때 유용.
-> 일반적으로 HTML 요소나 다른 컴포넌트를 래핑하거나 확장할 때, ref
가 필요하지 않은 경우에 사용됨.
이를 통해 타입 정의를 재사용하면서 불필요한 ref
관련 오류를 방지하고 코드의 가독성과 안정성을 높일 수 있음.