Todavía soy un novato en React y en muchos ejemplos en Internet, veo esta variación en la representación de elementos secundarios que encuentro confuso. Normalmente veo esto:
class Users extends React.Component {
render() {
return (
<div>
<h2>Users</h2>
{this.props.children}
</div>
)
}
}
Pero luego veo un ejemplo como este:
<ReactCSSTransitionGroup
component="div"
transitionName="example"
transitionEnterTimeout={500}
transitionLeaveTimeout={500}
>
{React.cloneElement(this.props.children, {
key: this.props.location.pathname
})}
</ReactCSSTransitionGroup>
Ahora entiendo la API, pero los documentos no aclaran exactamente cuándo debería usarla.
Entonces, ¿qué hace uno que el otro no puede? ¿Alguien podría explicarme esto con mejores ejemplos?
Respuestas:
Editar:
En cambio, mire la respuesta de Vennesa , que es una mejor explicación.
Original:
En primer lugar, el
React.cloneElement
ejemplo solo funciona si su hijo es un solo elemento React.Porque casi todo
{this.props.children}
es el que quieres. La clonación es útil en algunos escenarios más avanzados, donde un padre envía un elemento y el componente hijo necesita cambiar algunos accesorios en ese elemento o agregar cosas como ref para acceder al elemento DOM real.En el ejemplo anterior, el padre que le da al hijo no conoce el requisito de clave para el componente, por lo tanto, crea una copia del elemento que se le da y agrega una clave basada en algún identificador único en el objeto. Para obtener más información sobre lo que hace la clave: https://facebook.github.io/react/docs/multiple-components.html
fuente
props.children
no son los niños reales; Es eldescriptor
de los niños. Así que en realidad no tienes nada que cambiar; no se puede cambiar ningún accesorio ni editar ninguna funcionalidad; solo puedesread from it
. Si necesita realizar alguna modificación, debe crearnew elements
utilizandoReact.CloneElement
.https://egghead.io/lessons/react-use-react-cloneelement-to-extend-functionality-of-children-components
Un ejemplo:
función principal de renderizado de un componente como
App.js
:ahora digamos que necesita agregar un
onClick
a cada hijo deParagraph
; entonces en tuParagraph.js
puedes hacer:entonces simplemente puedes hacer esto:
Nota: la
React.Children.map
función solo verá lostop level
elementos, no ve ninguna de las cosas que esos elementos representan; lo que significa que está proporcionando los accesorios directos a los niños (aquí los<Sentence />
elementos). Si necesita que los accesorios se transmitan aún más, digamos que tendrá<div></div>
uno dentro de los<Sentence />
elementos que quiere usar elonClick
accesorio, entonces, en ese caso, puede usar elContext API
para hacerlo. Hacer que elParagraph
proveedor y losSentence
elementos sean consumidores.fuente
React.Children.map
junto conReact.cloneElement
como señala @vennesa, es muy poderosoDe hecho,
React.cloneElement
no está estrictamente asociado conthis.props.children
.Es útil siempre que necesite clonar elementos de reacción (
PropTypes.element
) para agregar / anular accesorios, sin querer que el padre tenga conocimiento sobre esos componentes internos (por ejemplo, adjuntar controladores de eventos o asignarkey
/ref
atributos).También los elementos de reacción son inmutables .
Sin embargo, el
children
accesorio en React se usa especialmente para contención (también conocido como composición ), emparejamiento conReact.Children
API yReact.cloneElement
componente que usa accesorios. Los niños pueden manejar más lógica (por ejemplo, transiciones de estado, eventos, mediciones DOM, etc.) internamente mientras ceden la parte de renderizado donde sea que se use, React Router<switch/>
o componente compuesto<select/>
son algunos buenos ejemplos.Una última cosa que vale la pena mencionar es que los elementos de reacción no se limitan a props.children.
Pueden ser lo que los apoyos que tenga sentido, la clave es definir un contrato bueno para el componente, de manera que los consumidores de que pueden ser desacoplados de los detalles de implementación subyacentes, independientemente de si se está usando
React.Children
,React.cloneElement
o inclusoReact.createContext
.fuente