Published on

ReactNode & ReactElement & JSX.Element

Authors
  • avatar
    Name
    Luffy Yeon
    Twitter

ReactNode & ReactElement & JSX.Element

타입스크립트 마이그레이션중 리엑트 컴포넌트를 반환 혹은 props로 children으로 받는 경우 타입 정의에 혼란이 왔다. 여러명이서 마이그레이션을 하다 보니 누군가는 ReactNode 또 다른 사람은 JSX.Element를 사용... 나조차도 어떤 곳에는 ReactElement로 지정하여 사용하고 있었다.


각 타입이 어떤 곳에 쓰는 것이 좋은지 정리할 필요성이 있다고 생각하여 위 타입들이 지정하는 바를 정리해본다.


ReactNode

ReactNode는 가장 넓은 타입을 가지는 타입이라고 할 수 있으며 ReactElement와 Javascript 원시 타입을 포함한다. ReactNode는 클래스 컴포넌트 render() 메소드의 반환 값으로 사용된다.

type ReactText = string | number
type ReactChild = ReactElement | ReactText
interface ReactNodeArray extends Array<ReactNode> {}
type ReactFragment = {} | ReactNodeArray
type ReactNode = ReactChild | ReactFragment | ReactPortal | boolean | null | undefined


ReactElement

ReactElement는 type과 props를 가지는 타입으로 제네릭으로 props 및 type의 타입을 지정할 수 있다. ReactElement는 함수형 컴포넌트의 반환 값으로 사용된다.

interface ReactElement<
P = any,
T extends string | JSXElementConstructor<any> = string | JSXElementConstructor<any>
> {
type: T
props: P
key: Key | null
}


JSX.Element

JSX.Element는 ReactElement 제네릭 타입에 any가 지정된 타입이다. JSX.Element는 글로벌 네임스페이스로 정의되어있어 각 라이브러리에서 지정하는 방식으로 설정될 수 있다. 아래는 React에 지정된 JSX.Element이다.

declare global {
namespace JSX {
interface Element extends React.ReactElement<any, any> { }

현재 진행하고 있는 프로젝트에서는 기본적으로 함수형 컴포넌트를 사용하고 있다. 함수형 컴포넌트는 StatelessComponent로 지정되지만, 함수형 컴포넌트의 타입을 정의하는 것에 따라 반환되는 타입이 조금 상이 할 수 있다.


아래는 함수형 컴포넌트의 props를 props 자체에 타입을 지정하는 형태로 해당 형태로 함수형 컴포넌트를 사용할 시 반환 값은 JSX.Element로 지정된다.


react element type

하지만 React.FC를 사용하여 함수형 컴포넌트 타입을 지정할 시 React.FC 타입으로 지정되어 해당 반환 값은 ReactElement<any, any> | null로 지정된다.

type StatelessComponent<P = {}> = FunctionComponent<P>
type FC<P = {}> = FunctionComponent<P>
interface FunctionComponent<P = {}> {
(props: PropsWithChildren<P>, context?: any): ReactElement<any, any> | null
propTypes?: WeakValidationMap<P> | undefined
contextTypes?: ValidationMap<any> | undefined
defaultProps?: Partial<P> | undefined
displayName?: string | undefined
}


함수형 컴포넌트에 만약 반환 값 null이 포함되는 경우에는 React.FC를 사용할 경우 반환 값 타입에 null이 포함되지만 React.FC를 사용하지 않은 경우에는 union 타입으로 null을 지정해 주어야 하는 번거로움이 있을 수 있다.


본인이 지정한 클래스, 함수형 컴포넌트에 따른 타입을 지정하거나 반환 값에 null 포함 여부에 따른 반환 값 타입을 지정하여 사용하는 것이 정확한 타입 추론이 될 수 있지 않을까 생각한다.


때로는 아래와 값이 컴포넌트 반환 타입을 지정하여 사용하기도 한다고 한다.

type ComponentReturnType =
| ReactElement
| Array<ComponentReturnType>
| string
| number
| boolean
| null // Note: undefined is invalid



[Ref]: