ReactNode는 React의 jsx문법에 사용되는 거의 모든 code들에 해당한다
type ReactText = string | number;
type ReactChild = ReactElement | ReactText;
interface ReactNodeArray extends Array<ReactNode> {}
type ReactFragment = {} | ReactNodeArray;
type ReactNode = ReactChild | ReactFragment | ReactPortal | boolean | null | undefined;
ReactNode의 type definition을 보면 Text(string) | Child(Element) | ReactNodeArray(Child[]) 등을 포함하고 있다.
interface ReactElement<
P = any,
T extends string |
JSXElementConstructor<any> = string |
JSXElementConstructor<any>{
type: T;
props: P;
key: Key | null;
}
ReactElement는 위와 같은 type을 가진 object를 return한다.
또한 ReactNode의 type 중 하나인 것을 알 수 있다.
JSX.Element는 ReactElement의 특정 타입과 같다. JSX.Element의 generic interface가 ReactElement이기 때문이다.
// 글로벌로 정의된 JSX
declare global {
namespace JSX { // Element가 React.Element를 상속받고 있다.
interface Element extends React.Element<any, any> {}
}
}
한 마디로 react에서 html을 쓰기 위한 jsx는 JSX.Element type이다.
type React.FC<P={}> = React.FunctionComponent<P>
Props의 Type만 generic으로 받는 간단한 타입이다.
type objectType = {};
export dafault function Greeting({data1, data2}: objedctType){}
함수선언식의 장점은 호이스팅을 통한 로직분리와 export default를 통해 내보낼 컴포넌트임을 명시할 수도 있다. 하지만 호이스팅은 예상치 못한 결과를 낼 수도 있다.
type obejctType = {};
const Greeting: React.FC<objectType> = ({data1, data2}: obejectType) => {};
export default Greeting;
함수표현식은 props를 generics에 넣기 때문에 props에는 항상 children 속성이 존재하게 된다. 하지만 React.FC에는 generic타입을 넣을 수는 있지만 generics를 허용하지 않는다. any를 방지할 수 없다.
하지만 클로저와 같은 표현식의 장점도 있다.
그런데 defaultProps를 쓸 수도 있지만 쓸 수도 없다.(?) 따라서 함수의 매개변수에 기본 값을 주어 사용해야 한다.
React의 공식 문서에서는 함수선언식을 사용하고 있다. 표현식은 defaultProps도 사용하지 못하는 이슈가 있기 때문에 그런 것 같다. Typescript를 사용하는 이유는 정적인 type 체크를 하기 위해서인데 optional한 chilren props를 가지고 있어 따로 명시도 해줘야 하는 불편함이 있어 기피한다.
자기전에 어려워서 글을 쓰게 되었는데 쉬워서 머쓱하다..^^