본문 바로가기
Tech/React

ReactNode vs ReactElement vs JSX.Element

by egas 2021. 7. 7.

render()

render() 메소드는 class component에서만 필수적으로 필요하다.

 

render() 메소드가 호출되면 this.props와 this.state를 활용해서 아래 타입 중 하나를 반환한다.

 

  • React elements: JSX를 통해 생성된다. 그 예시로 <div />와 <MyComponent />는 React가 DOM 노드 또는 사용자가 정의한 컴포넌트를 만들도록 지시하는 React 엘리먼트이다.
  • Arrays and fragments: render()를 통해서 여러 개의 element들을 반환한다.
  • Portals: 별도의 DOM 하위 트리에 자식 엘리먼트를 렌더링 하게 해준다.
  • String and numbers: 이 값들은 DOM 상에 텍스트 노드로서 렌더링된다.
  • Booleans or null: 아무것도 렌더링하지 않는다. (대부분의 경우 return test && <Child /> 패턴을 지원하는 데에 사용된다. test는 boolean 값이다.)

render() 함수는 순수해야 한다. 즉, 컴포넌트의 state를 변경하지 않고, 호출될 때마다 동일한 결과를 반환해야하며, 브라우저와 직접적으로 상호작용을 하지 않는다.

 

ReactNode

render() 메소드를 통해서 반환되는 값이 ReactNode이다. ReactNode는 위 반환값들을 포함한다. 즉, Class Component의 반환 값은 ReactNode이다.

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

JSX 문법은 React.createElement(component, props, ...children)을 사용하도록 코드가 변환된다. 함수 Component는 ReactElement를 반환한다.

 

ReactElement는 type과 props가 있는 객체이다.

type Key = string | number

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

 

아래 두 코드는 동치이다.

class Hello extends React.Component {
  render() {
    return <div>Hello {this.props.toWhat}</div>;
  }
}

ReactDOM.render(
  <Hello toWhat="World" />,
  document.getElementById('root')
);
class Hello extends React.Component {
  render() {
    return React.createElement('div', null, `Hello ${this.props.toWhat}`);
  }
}

ReactDOM.render(
  React.createElement(Hello, {toWhat: 'World'}, null),
  document.getElementById('root')
);

 

JSX.Element

JSX.Element는 props와 any type가 generic type인 ReactElement 이다. JSX는 React의 global namespace에 있기 때문에, 다양한 라이브러리들이 자체적으로 JSX를 구현하여 사용할 수 있다. 

 

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

 


TL;DR

Functional Component 반환 값: ReactElement.

Class Component 반환 값: ReactNode


추가 정보

함수형은 "stateless components" 이다.

 interface StatelessComponent<P = {}> {
    (props: P & { children?: ReactNode }, context?: any): ReactElement | null;
    // ... doesn't matter
}

React.FC / React.FunctionComponent

React.FC와 함께 component를 정의하면 ReactNode type의 children을 암시적으로 가져온다. 이것은 모든 component는 children을 허용한다는 뜻이다.

 

참고 자료

 

https://reactjs.org/docs/react-component.html#render

 

React.Component – React

A JavaScript library for building user interfaces

reactjs.org

https://reactjs.org/docs/react-api.html#createelement

 

React Top-Level API – React

A JavaScript library for building user interfaces

reactjs.org

https://stackoverflow.com/questions/58123398/when-to-use-jsx-element-vs-reactnode-vs-reactelement

 

When to use JSX.Element vs ReactNode vs ReactElement?

I am currently migrating a React application to TypeScript. So far, this works pretty well, but I have a problem with the return types of my render functions respectively my function components. S...

stackoverflow.com

https://stackoverflow.com/questions/53688899/typescript-and-react-children-type

 

TypeScript and React - children type?

I have a very simple functional component as follows: import * as React from 'react'; export interface AuxProps { children: React.ReactNode } const aux = (props: AuxProps) => props.chi...

stackoverflow.com

https://github.com/facebook/create-react-app/pull/8177

 

Remove React.FC from Typescript template by Retsam · Pull Request #8177 · facebook/create-react-app

This removes React.FC from the base template for a Typescript project. Long explanation for a small change: React.FC is unnecessary: it provides next to no benefits and has a few downsides. (See b...

github.com

 

728x90

'Tech > React' 카테고리의 다른 글

useEffect 정리  (0) 2021.07.22
[Typescript] CRA에서 http-proxy-middleware 사용법  (0) 2021.07.14
react 리뷰 정리  (0) 2021.06.15
React component  (0) 2021.05.29
선언형 프로그래밍과 명령형 프로그래밍  (0) 2021.05.11

댓글