TypeScriptSTUDY _ 8장 . JSX에서 TSX로 [ 8.1 리액트 컴포넌트의 타입 ]

zeroha·2024년 12월 23일
0

TypeScriptStudy

목록 보기
24/32
post-thumbnail

8.1 리액트 컴포넌트의 타입

.
.
.

1. 클래스 컴포넌트의 타입

클래스 컴포넌트가 상속받는 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 타입을 제네릭으로 받고 있다.


2. 함수 컴포넌트 타입

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>
);

3. Children props 타입 지정

type PropsWithChildren<P> = P & { children?: ReactNode | undefined };

가장 보편적인 children 타입 : ReactNode | undefined
ReactNode : 여러 타입 포함, 더 구체적으로 타이핑하는 용도에는 적합 x
( ex. 특정 문자열만 허용하고 싶을 때 : children에 대해 추가로 타이핑해줘야 함. )


4. render 메서드와 함수 컴포넌트의 반환 타입 - React ReactElement vs JSX.Element vs React.ReactNode

리액트는 실제 DOM x -> 가상의 DOM 기반 렌더링 ... 가상 DOM의 엘리먼트 : React ReactElement 형태로 저장.
즉, React ReactElement 타입은 리액트 컴포넌트를 객체 형태로 저장하기 위한 포맷...

React 엘리먼트(React Element)
: React에서 UI를 구성하는 가장 작은 단위.
: HTML 태그나 컴포넌트의 구조를 표현하는 객체(Object)

JSX.Element 타입 : 리액트의 ReactElement를 확장하고 있는 타입.
글로벌 네임스페이스에 정의되어 있어 외부 라이브러리에서 컴포넌트 타입을 재정의할 수 있는 유연성을 제공.->컴포넌트 타입을 재정의하거나 변경하는 것이 용이해짐.

글로벌 네임스페이스
: 프로그래밍에서 식별자(변수, 함수, 타입 등)가 정의되는 전역적인 범위.
즉, 어떠한 파일이든지 해당 스코프에서 선언된 식별자는 모든 곳에서 접근할 수 있음.

  • ReactElement, ReactNode, JSXElement 포함관계


5. ReactElement, ReactNode, JSXElement 활용하기 (리액트의 요소) | 6. 사용예시

1) ReactElement

리액트 엘리먼트를 생성하는 createElement 메서드
: JSX가 createElement 메서드를 호출하기 위한 문법

JSX : 자바스크립트의 확장 문법. 리액트에서 UI를 표현하는 데 사용됨.

즉, JSX는 리액트 엘리먼트를 생성하기 위한 문법이며 트랜스파일러는 JSX 문법을 createElement 메서드 호출문으로 변환하여 리액트 엘리먼트를 생성함.

리액트는 이런 식으로 만들어진 리액트 엘리먼트 객체를 읽어서 DOM을 구성.

즉, ReactElement타입은 JSX의 createElement메서드 호출로 생성된 리액트 엘리먼트를 나타내는 타입.

  • 원하는 컴포넌트의 props르 ReactElement의 제네릭으로 지정 가능.

2) ReactNode

ReactChild 타입 : ReactElement | string | number로 정의 -> ReactElement보다는 넒은 범위를 갖고 있음.

ReactNode는 ReactChild + boolean + null + undefined 등 훨씬 넓은 범주의 타입을 포함.

즉, ReactNode는 리액트의 render함수가 반환할 수 있는 모든 형태를 담고 있음.

  • prop으로 리액트 컴포넌트가 다양한 형태를 가질 수 있게 하고 싶을 때 우용하게 사용.

3) JSXElement

: ReactElement의 제네릭

즉, JSXElement는 ReactElement의 특정 타입으로 props와 타입 필드를 any로 가지는 타입.

  • 리액트 엘리먼트를 prop으로 전달받아 render props 패턴으로 컴포넌트를 구현할 때 유용히게 활용가능.

7. 리액트에서 기본 HTML 요소 타입 활용하기

1) DetailedHTMLProps와 ComponentWithoutRef : HTML 태그의 속성 타입 활용

  • DetailedHTMLProps
    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 이벤트 핸들러 타입과 동일하게 할당되는 것을 확인 가능

  • ComponentWithoutRef
type NativeButtonType = React.ComponentPropsWithoutRef<"button">;
type ButtonProps = {
onClick?: NativeButtonType["onClick"];
};

: 마찬가지로 button onClick 이벤트 핸들러 타입과 동일하게 할당되는 것을 확인 가능

2) 언제 ComponentPropsWithoutRef를 사용하면 좋을까

ref
: 생성된 DOM 노드나 리액트 엘리먼트에 접근하는 방법

ComponentPropsWithoutRef는 특정 React 컴포넌트 타입의 props를 가져오되, ref 속성을 제외한 타입을 사용하고 싶을 때 유용.
-> 일반적으로 HTML 요소나 다른 컴포넌트를 래핑하거나 확장할 때, ref가 필요하지 않은 경우에 사용됨.

이를 통해 타입 정의를 재사용하면서 불필요한 ref 관련 오류를 방지하고 코드의 가독성과 안정성을 높일 수 있음.


도서참조 : 우아한 타입스크립트 with 리액트
profile
하 영

0개의 댓글

관련 채용 정보