Saltar al contenido

Cómo renderizar un componente dinámicamente basado en una configuración JSON

Para renderizar los componentes basados en la clave de componentes en la configuración de JSON, primero necesitamos crear un objeto que mapee los componentes con la clave de componentes.

123456789constKeysToComponentMap={ card:Card, img:CardImg, text:CardText, body:CardBody, title:CardTitle, subtitle:CardSubtitle, button:Button};

js

Cómo renderizar un componente dinámicamente basado en una configuración JSON
Cómo renderizar un componente dinámicamente basado en una configuración JSON

Como pueden ver, he mapeado la clave del componente con el correspondiente componente de Reactstrap.

En la parte superior, importaremos todos los componentes necesarios.

123456789import{Card,CardImg,CardText,CardBody,CardTitle,CardSubtitle,Button}de "reactstrap";

jsx

En la función renderer(), primero comprobaremos si la clave existe en el objeto KeysToComponentMap.

12345constrenderer=config=;{if(typeofKeysToComponentMap[config.component]!=="undefined"){// ..}};

jsx

A continuación usaremos la función React.createElement() para renderizar el componente.

React.createElement()

La función React.createElement() crea y devuelve un nuevo elemento React del tipo dado.

12345React.createElement( type,[props],[...children]);

js

Toma tres argumentos: el tipo, la utilería y los niños.

El tipo aquí es el componente React que queremos renderizar; props son los datos o propiedades que queremos pasar al componente, y children es otro componente que queremos pasar entre los elementos DOM.

El JSX que escribimos en React se compila en una llamada a la función React.createElement() con la ayuda de un compilador de babel.

Veamos un ejemplo sencillo.

12345letWelcomeText=React.createElement("h1",{ style:{ color: "blue"}}, "This is a welcome text");

jsx

Lo anterior se representa en el DOM como

123<h1>; Este es un texto de bienvenida</h1>;

html

Ahora que entiendes cómo funciona el método React.createElement(), volvamos a nuestra búsqueda original.

A la función createElement le pasaremos como primer argumento el componente que queremos renderizar, es decir, KeysToComponentMap[config.component]. Obsérvese que aquí para acceder al objeto, estamos utilizando la notación entre paréntesis [] y no la notación punto .

12345functionrenderer(config){if(typeofKeysToComponentMap[config.component]!=="undefined"){returnReact.createElement(KeysToComponentMap[config.component]);}}

jsx

La notación entre paréntesis [] nos permite acceder dinámicamente a una propiedad usando una variable. Por lo tanto, es más fácil obtener el componente de esta manera, en lugar de tener un bloque de caja de conmutación para determinar qué componente debe ser renderizado.

Si ejecuta el código que tenemos hasta ahora, notará que el componente se renderiza en el DOM. Eso significa que vamos en la dirección correcta.

123<div...
html

Ahora, llevemos esto más allá y hagamos que los componentes del niño también.

Tenemos que comprobar si los componentes del niño existen. Entonces mapea cada componente hijo y pásalo a la función renderer(), haciéndolo recursivo.

1config.children&& config.children.map(c=>renderer(c));

jsx

Esto se ve bien. Vamos a probarlo.

1234567891011functionrenderer(config){if(typeofKeysToComponentMap[config.component]!=="undefined"){returnReact.createElement(KeysToComponentMap[config.component],{},{ config.children&& config.children.map(c=>renderer(c))});}}

jsx

¡Maldición! Si tienes el error config.children.map no es una función, no te preocupes; eso es porque no todos los niños son del tipo de un array, y no hemos tenido eso en cuenta. Por ejemplo, el componente del botón tiene hijos de tipo cadena. Así que reescribamos nuestra condición.

1234567891011121314functionrenderer(config){if(typeofKeysToComponentMap[config.component]!=="undefined"){returnReact.createElement(KeysToComponentMap[config. component],{},{ config.children&&(typeof config.children==="string"? config.children: config.children.map(c={N-]};renderer(c))});}}

jsx

Yay! Tenemos los componentes de los niños para renderizar. Pero espera, todavía tenemos un componente de imagen que no aparece.

Para eso, necesitamos pasar el SRC como una propiedad en el argumento de apoyo.

12345678910111213141516functionrenderer(config){if(typeofKeysToComponentMap[config.component]!=="undefined"){returnReact.createElement(KeysToComponentMap[config. component],{ src: config.src},{ config.children&&(typeof config.children==="string"? config.children: config.children.map(c=>renderer(c)))});}}

jsx

Ahí lo tienes. Hemos logrado renderizar un componente de forma dinámica a partir de una configuración JSON.