No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Aprende todo un fin de semana sin pagar una suscripción 🔥

Aprende todo un fin de semana sin pagar una suscripción 🔥

Regístrate

Comienza en:

5D
2H
27M
25S

React.Children y React.cloneElement

11/19
Recursos

Aportes 31

Preguntas 11

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

o inicia sesión.

11.-React.Children y React.cloneElement


Para poder pasar propiedades especiales a los componentes hijos de nuestros componentes contenedores cuando hacemos composición.


Cuando enviamos más de un componente o elemento hijo al que use CloneElement, la app deja de funcionar y suelta un error. CloneElement necesita recibir un elemento de react, cuando children es más de un componente entonces tenemos un array, para esto existe React.Children que nos ayuda a que CloneElement entienda sin importar cuantos elementos vienen en el props.children.

function TodoHeader({ children, loading }) {
  //No importa si viene un elemento, o dos o null siempre nos devuelve un array

  return (
    <header>
      {React.Children.toArray(children).map((child) =>
        React.cloneElement(child, { loading: loading })
      )}
    </header> //Por cada child vamos a llamar a clone element.
  ); //Crear elemento a partir de otro (elemento, objeto con las props que queramos que tenga)
}

No son las herramientas más populares pero pueden ser muy útiles cuando queremos compartir una o ciertas props a los componentes hijos de un componente contenedor.

Imagino un componente que se renderiza en diferentes partes pero en alguna de ellas toma algunas propiedades diferentes ya sea estilos o textos. se podría en ciertas partes usar React.cloneElemet para no tener que modificar otros componentes padres del aplicativo.

🗄️ React.Children y React.cloneElement

Apuntes

React.cloneElement

  • Con esta característica de React podemos crear elementos de Nodos React
  • Cabe aclarar que esta funciona con un unico nodo, en caso de aplicarla en un conjunto de los mismos podemos ayudarnos de React.Children

React.Children

  • Nos permite manipular la prop children entre uno de sus usos podemos volver un conjunto de nodos react a un array

Me pareció sencillo trabajar así también jeje, no se qué opinen:

import React from "react";

function TodoHeader({ children, loading }) {
  return (
    <header>
      {
        [...children].map((child, index) => (
          React.cloneElement(child, { loading, key: index })
        ))
      }
    </header>
  );
}

export {
  TodoHeader
};

 {React.Children.toArray(children).map((child) => React.cloneElement(child, { loading }))}

Pónganle un:

.TodoSearch__container {
   transition: 1s;
}

Y verán que bonito

Recomiendo mucho el link que adjunto Juan de Medium! Buenísimo, me lo dejó super claro

React.Children tiene varias utilidades para trabajar con props.children. Para profundizar en que hacen les dejo lo siguiente:
React.Children

React.Children.map( children, function() )

React.Children.forEach( children, function() )

React.Children.count( children )

React.Children.only( children )

React.Children.toArray( children )

Con respecto a React.cloneElement( children, { props } ) me sirve para cuando tengo varios hijos dentro de un componente y casualmente todos ellos usan las mismas props que el padre además de otras propias. Por tanto para evitar escribirle las mismas props a cada hijo, las clonamos del padre y con métodos de array las repartimos entre los hijos.
React.cloneElement

Muy buena explicación! Solo un apunte, actualmente cloneElement está desaconsejado por React y en su documentación te muestra diferentes alternativas: https://beta.reactjs.org/reference/react/cloneElement
Un saludo!

🤯 despacio despacio cerebrito.
Wow, esto sí que me voló la cabeza.

Está bueno conocer este tipo de herramientas que no son tan utilizadas, pero existen y uno puede toparse con ellas en un proyecto laboral.

Los “React Children” se usan principalmente para dar estructura y organizar el contenido dentro de un componente React. Al utilizar componentes en React, se puede dividir el contenido en diferentes partes y organizarlo de manera más clara y sencilla. Además, esto permite reutilizar código de manera más eficiente, ya que puedes crear componentes genéricos que pueden ser utilizados en diferentes partes de tu aplicación.

React.cloneElement es una función de React que se utiliza para clonar un elemento y pasarle nuevas propiedades. Esto puede ser útil en casos donde quieras crear una copia de un componente existente y modificar algunas de sus propiedades, pero sin tener que crear un nuevo componente desde cero. Por ejemplo, si tienes un componente que muestra un botón y quieres cambiar el color del botón en una parte de tu aplicación, puedes utilizar React.cloneElement para clonar el componente del botón y pasarle una nueva propiedad de color.

Para los que quieran una animación de carga que va acorde al proyecto a mi parecer les dejo un fade en css:

.TodoCounter--loading {
  animation: fade 1s infinite;
}

/* infinite fade animation */
@keyframes fade {
  0% {
    opacity: 0.5;
  }
  50% {
    opacity: 0.3;
  }
  100% {
    opacity: 0.5;
  }
}

React.Children y React.cloneElement , me parecieron bastante utiles para pasar props entre varios hijos y contenedores, con eso no tener que estar pasando todos los props a cada hijo directamente

Para los que estén usando Typescript y sufran un poco con los tipos les comparto lo que hice.

  • Children en el componente de Header lo difiní como un array de ReactElement (Es mejor usar ReactElement ya que es más específico que ReactNode).
  • A los componentes del searchbar y del título les puse como nuleable la propiedad de “loading”
interface TodoHeaderType {
    children : ReactElement[],
    loading : boolean,
}

function TodoHeader({children, loading} : TodoHeaderType) {
    return (
        <header>
            {
                React.Children
                    .map(children, child => React.cloneElement(child, {loading}))
            }
        </header>
    );
}

export default TodoHeader;

En mi app, le estaba enviando el estado “darkMode” a CADA componente para asignar estilos oscuros… esta funcionalidad me arregla la vida!

Esto es lo que tenia tiempo queriendo saber como se hacia, pense no era posible algo asi, excelente clase.

Un uso interesante puede ser si se necesita que todos los componentes dentro de un container tengan cierto color o propiedad visual, y que si están fuera de ese container no tengan ese color. O incluso poder definir ese color dependiendo del container. Se aplica el clone element a todos los hijos del container y se le añade la propiedad deseada.

Me voló la cabeza el uso de estás herramientas!

no se ustedes, pero me parece innecesario complicarme la vida xd

podria ser para evitar el DRY, pero no lo se

<h2 className="TodoCounter">{!loading && `Has completado ${completedTodos} de  ${totalTodos}`} TODOs</h2>

¿Qué es lo que me encanta de estos cursos? que JuanDC nos enseña muchas formas de hacer lo mismo y eso es genial porque tienes varias opciones para solucionar un problema, gracias JuanDC!!!

BEM (Block Element Modifier) es un estandar para crear nombres de clases que sigue la estructura:

block__element--modifier

Por lo que la clase para el texto en TodoCounter podría quedar algo así:

.TodoCounter__text--disabled {
  opacity: 25%;
}

siempre que intentaba poner children en un componente visual studio me importaba Children. Ahora por fin se para que es.

Yo lo había pensado algo así, para que lo mostrara según había Todos o no

<TodoHeader>
				<Title>Todo tasks</Title>
				{totalTodos > 0 && 
						<TodoSearch 
							search={searchValue} 
							setSearch={setSearch} />
				}
			</TodoHeader>

Resumen

  • React.cloneElement sirve para clonar un componente y agregarle propiedades.
  • React.Children.toArray al enviarle la prop children siempre nos devuelve un arreglo con nuestros elementos o componentes de children.

jejjejejej ese error del minuto 12:05 se solucionaba dandole exactamente el index del children


  { React.cloneElement(children[0], {loading}) }
  { React.cloneElement(children[1], {loading}) }

Inquietud

Buenas tardes a todos, tengo una inquietud porque en este curso no se esta dejando Archivos de la clase?, es muy ganador encontrar los archivos para un mejor entendimiento. O en su caso un repositorio de git de cada clase. Espero una repuesta agradezco si es del profesor @JUAN DAVID CASTRO

Una vez use React.Children y React.cloneElement para crear un componente de formulario. En el que pasandole ciertas propiedades terminada pasandole los valores a todos sus hijos (inputs)

Me parece que está súper práctico para agregar soporte de idiomas! Dejo un ejemplo de cómo lo distribuyo en mi header, aunque no pude usar Children 😅 👇

Ejemplo: https://juliantoro91.github.io/TAPP-react-todo-app/

En App.js

    <TodoHeader
        loading={loading}
        languageSupport={languageSupport}
        languageShifter={
          <LanguageShifter
            saveLanguage={saveLanguage} />}
        todoCounter={
          <TodoCounter
            tasksState={tasksState}
          />}
      />

En el TodoCounter del header

<div className="header-todo-counter">{ react.cloneElement(todoCounter, { loading, languageSupport }) }</div>

Repositorio Github: https://github.com/juliantoro91/TAPP-react-todo-app

Me parece muy útil para hacer animación con clases de CSS, simplifica mucho la lógica que hay que implementar .-.