JSX Element, React Node, React Element

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, specifically in my functional components.

Cut a long story short, I have these questions dur…


This content originally appeared on DEV Community and was authored by DEV Community

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, specifically in my functional components.

Cut a long story short, I have these questions during my learning process:

  1. What is the difference between JSX.ElementReactNode and ReactElement?
  2. Why do the render methods of class components return ReactNode, but functional components return ReactElement?

What is the difference between JSX.ElementReactNode and ReactElement?

A ReactElement is an object with a type and props.

type Key = string | number

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

A ReactNode is a ReactElement, a ReactFragment, a string, a number or an array of ReactNodes, or null, or undefined, or a boolean:

A ReactNode is a ReactElement, a ReactFragment, a string, a number or an array of ReactNodes, or null, or undefined, or a boolean:

type ReactText = string | number;
type ReactChild = ReactElement | ReactText;

interface ReactNodeArray extends Array<ReactNode> {}
type ReactFragment = {} | ReactNodeArray;

type ReactNode = ReactChild | ReactFragment | ReactPortal | boolean | null | undefined;

JSX.Element is a ReactElement, with the generic type for props and type being any. It exists, as various libraries can implement JSX in their own way, therefore JSX is a global namespace that then gets set by the library, React sets it like this:

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

By example:

<p> // <- ReactElement = JSX.Element
   <Custom> // <- ReactElement = JSX.Element
     {true && "test"} // <- ReactNode
  </Custom>
 </p>

Why do the render methods of class components return ReactNode, but functional components return ReactElement?

they do return different things. Components return:

render(): ReactNode;

tl;dr: It is a current TS type incompatibility not related to core React.

  • TS class component: returns ReactNode with render(), more permissive than React/JS
  • TS function component: returns JSX.Element | null, more restrictive than React/JS

In principle, render() in React/JS class components supports the same return types as a function component. With regard to TS, the different types are a type inconsistency still kept due to historical reasons and the need for backwards compatibility.

Ideally a valid return type would probably look more like this:

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

If you guys have other thoughts leave a comment I'll update the post base on your solutions as well.. cheers🍻


This content originally appeared on DEV Community and was authored by DEV Community


Print Share Comment Cite Upload Translate Updates
APA

DEV Community | Sciencx (2022-03-12T00:12:52+00:00) JSX Element, React Node, React Element. Retrieved from https://www.scien.cx/2022/03/12/jsx-element-react-node-react-element/

MLA
" » JSX Element, React Node, React Element." DEV Community | Sciencx - Saturday March 12, 2022, https://www.scien.cx/2022/03/12/jsx-element-react-node-react-element/
HARVARD
DEV Community | Sciencx Saturday March 12, 2022 » JSX Element, React Node, React Element., viewed ,<https://www.scien.cx/2022/03/12/jsx-element-react-node-react-element/>
VANCOUVER
DEV Community | Sciencx - » JSX Element, React Node, React Element. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2022/03/12/jsx-element-react-node-react-element/
CHICAGO
" » JSX Element, React Node, React Element." DEV Community | Sciencx - Accessed . https://www.scien.cx/2022/03/12/jsx-element-react-node-react-element/
IEEE
" » JSX Element, React Node, React Element." DEV Community | Sciencx [Online]. Available: https://www.scien.cx/2022/03/12/jsx-element-react-node-react-element/. [Accessed: ]
rf:citation
» JSX Element, React Node, React Element | DEV Community | Sciencx | https://www.scien.cx/2022/03/12/jsx-element-react-node-react-element/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.