사용자가 만든 사용자 정의 컴포넌트로 스코프 내의 식별자에 의해 사용됨
Element를 선언하는 방법은 두가지가 있음.
1. Function Component (FC)
2. Class Component
타스에서는 함수형 컴포넌트로 표현을 해석을 기본으로 하고, 함수형 컴포넌트가 확인되지 않으면 클래스 컴포넌트로 해석함. 기본적으로 JSX의 결과 타입은 any
이지만, JSX.element
인터페이스를 통해 해당 타입으로 변경 가능
클래스형 컴포넌트에서 render메소드를 통해 ReactNode
를 리턴하는 반면, 함수형 컴포넌트는 ReactElement
를 리턴. ReactElement는 React.createElement
로 컴파일 되며, JSX.Element
는 any타입의 props와 type을 가진 React.createElement
이다.
역사적인 이유와 하위호환성 문제로 두 컴포넌트의 리턴 타입이 다름.
따라서 함수형 컴포넌트를 사용한다면 리턴값의 기본 타입으로 JSX.element를 사용해주어야함.
FC는 Function Component의 약자로 그대로 넣어서 사용해도 돌아감
React.FC 사용시, Props의 타입을 Generic에 넣어서 사용
React.FC <string>
본 컴포넌트는 단순한 함수가 아니라 함수형 컴포넌트임을 명시해주는 역할로 화살표 함수를 사용해 컴포넌트를 정의할 때, 컴포넌트 타입을 정하기 위해 사용되기도 함.
const App : React.FC = () => {}
-> class component로 만든 경우, React.ClassComponent사용 가능
타입값이 JSX를 리턴하는 함수이므로 리턴값이 없다면 오류가 발생함
하지만 children이 옵션으로 들어가 있어, 컴포넌트 props의 타입이 정할 수 없는 단점이 있음.
children의 요소로 어떤 타입이 들어올 지 모르기 때문
const로 선언되는 컴포넌트를 변수로 생각하지 못하도록 React.FC로 타입을 지정해줌.
그래서 선언된 컴포넌트의 내장함수로 리액트 함수형 컴포넌트의 내장함수들을 사용할 수 있음.
그러나 아직 defaultprops를 아직 인식하지 못하는 성능상의 문제가 존재함.
Defaultprops에 대한 논쟁
defaultProps vs object default values
사람들이 선호하는 방식은 object default values
why ? 기존의 방식이 너무 복잡하고 FC로 defaultProps를 적용하기 위해선 별도의 처리가 필요함.
import * as React from "react";
type ComponentProps<T> = T extends React.ComponentType<infer P> | React.Component<infer P>
? JSX.LibraryManagedAttributes<T, P>
: never;
interface IProps {
name: string;
}
const defaultProps = {
age: 25,
};
const GreetComponent = ({ name, age }: IProps & typeof defaultProps) => (
<div>{`Hello, my name is ${name}, ${age}`}</div>
);
GreetComponent.defaultProps = defaultProps;
// later
const TestComponent = (props: ComponentProps<typeof GreetComponent>) => {
return <h1 />
};
// No error
const el = <TestComponent name="foo" />;
그래서 defaultProps를 사용하는 대신, object default value를 주는 것을 추천
type GreetProps = { age?: number };
const Greet = ({ age = 21 }: GreetProps) => // etc
// Use type inference; inferred return type is `JSX.Element | null`
const MyComp1 = ({ condition }: { condition: boolean }) =>
condition ? <div>Hello</div> : null
// Use explicit function return types; Add `null`, if needed
const MyComp2 = (): JSX.Element => <div>Hello</div>;
const MyComp3 = (): React.ReactElement => <div>Hello</div>;
// Option 3 is equivalent to 2 + we don't need to use a global (JSX namespace)
// Use built-in `FunctionComponent` or `FC` type
const MyComp4: React.FC<MyProps> = () => <div>Hello</div>;
컴포넌트의 리턴값을 설정한다. : JSX.Element
변수에게 타입을 설정한다. : React.FC<type>
Create react app에서는 React.FC 사용이 어려울 수 있음
https://stackoverflow.com/questions/58123398/when-to-use-jsx-element-vs-reactnode-vs-reactelement/59840095#59840095
최고에요!