Saltar al contenido

¿Cuándo usar JSX.Element vs ReactNode vs ReactElement?

Investigamos por distintos espacios y así darte la solución a tu dilema, si continúas con alguna duda déjanos la pregunta y te contestamos porque estamos para ayudarte.

Solución:

¿Cuál es la diferencia entre JSX.Element, ReactNode y ReactElement?

Un ReactElement es un objeto con un tipo y accesorios.

 type Key = string | number

 interface ReactElement

= string | JSXElementConstructor> null;

Un ReactNode es un ReactElement, un ReactFragment, un stringun número o un array de ReactNodes, o nullo indefinido, o un booleano:

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

interface ReactNodeArray extends Array 
type ReactFragment =  | ReactNodeArray;

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

JSX.Element es un ReactElement, con el tipo genérico para accesorios y el tipo es cualquiera. Existe, ya que varias bibliotecas pueden implementar JSX a su manera, por lo tanto, JSX es un espacio de nombres global que luego establece la biblioteca, React lo establece así:

declare global 
  namespace JSX 
    interface Element extends React.ReactElement  
  

Por ejemplo:

 

// <- ReactElement = JSX.Element // <- ReactElement = JSX.Element true && "test" // <- ReactNode

¿Por qué los métodos de representación de los componentes de clase devuelven ReactNode, pero los componentes de función devuelven ReactElement?

De hecho, devuelven cosas diferentes. Components retorno:

 render(): ReactNode;

Y las funciones son “componentes sin estado”:

 interface StatelessComponent

null; // ... doesn't matter

En realidad, esto se debe a razones históricas.

¿Cómo soluciono esto con respecto a null?

Escríbelo como ReactElement | null tal como reacciona. O deje que Typescript infiera el tipo.

fuente de los tipos

1.) ¿Cuál es la diferencia entre JSX.Element, ReactNode y ReactElement?

ReactElement y JSX.Element
son el resultado de invocar React.createElement directamente o a través de la transpilación JSX. es un objeto con type, props y key. JSX.Element es ReactElementcuyo props y type tener tipo anypor lo que son más o menos lo mismo.

const jsx = 
hello
const ele = React.createElement("div", null, "hello");

ReactNode se utiliza como tipo de retorno para render() en componentes de clase. También es el tipo predeterminado para children attribute con PropsWithChildren.

const Comp: FunctionComponent = props => 
props.children
// children?: React.ReactNode

Parece más complicado en las declaraciones de tipo React, pero es equivalente para:

type ReactNode =  | null | undefined;
// super type `` has absorbed *all* other types, which are sub types of ``
// so it is a very "broad" type (I don't want to say useless...)

Puede asignar casi todo a ReactNode. Por lo general, preferiría tipos más fuertes, pero podría haber algunos casos válidos para usarlo.


2.) ¿Por qué los métodos de representación de los componentes de clase devuelven ReactNode, pero los componentes de función devuelven ReactElement?

tl; dr: Es una incompatibilidad de tipo TS actual que no está relacionada con el núcleo de React.

  • Componente de clase TS: devoluciones ReactNode con render()más permisivo que React/JS

  • Componente de la función TS: devoluciones JSX.Element | nullmás restrictivo que React/JS

En principio, render() en los componentes de clase React/JS admite los mismos tipos de devolución que un componente de función. Con respecto a TS, los diferentes tipos son una inconsistencia de tipos que aún se mantiene debido a razones históricas y la necesidad de compatibilidad con versiones anteriores.

Idealmente, un tipo de retorno válido probablemente se parecería más a esto:

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

3.) ¿Cómo resuelvo esto con respecto a null?

Algunas opciones:

// Use type inference; inferred return type is `JSX.Element | null`
const MyComp1 = ( condition :  condition: boolean ) =>
    condition ? 
Hello
: null // Use explicit function return types; Add `null`, if needed const MyComp2 = (): JSX.Element =>
Hello
; const MyComp3 = (): React.ReactElement =>
Hello
; // 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 = () =>
Hello
;

Nota: Evitando React.FC no te salvará de la JSX.Element | null restricción de tipo de retorno.

Crear aplicación React lanzada recientemente React.FC de su plantilla, ya que tiene algunas peculiaridades como un implícito children?: ReactNode definición de tipo. entonces usando React.FC con moderación podría ser preferible.

En casos extremos, puede agregar una aserción de tipo o Fragmentos como solución alternativa:

const MyCompFragment: FunctionComponent = () => <>"Hello"
const MyCompCast: FunctionComponent = () => "Hello" as any 
// alternative to `as any`: `as unknown as JSX.Element | null`

Eres capaz de añadir valor a nuestro contenido contribuyendo tu experiencia en las crónicas.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *