Muchos lenguajes de plantilla tienen declaraciones de "ranuras" o "rendimiento", que permiten hacer algún tipo de inversión de control para envolver una plantilla dentro de otra.
Angular tiene la opción "transcluir" .
Rails tiene declaración de rendimiento . Si React.js tuviera una declaración de rendimiento, se vería así:
var Wrapper = React.createClass({
render: function() {
return (
<div className="wrapper">
before
<yield/>
after
</div>
);
}
});
var Main = React.createClass({
render: function() {
return (
<Wrapper><h1>content</h1></Wrapper>
);
}
});
Salida deseada:
<div class="wrapper">
before
<h1>content</h1>
after
</div>
Por desgracia, React.js no tiene un <yield/>
. ¿Cómo defino el componente Wrapper para lograr el mismo resultado?
Respuestas:
Tratar:
Consulte Múltiples componentes: elementos secundarios y accesorios de tipo de elementos secundarios en los documentos para obtener más información.
fuente
Utilizando
children
Esto también se conoce como
transclusion
en Angular.children
es un accesorio especial en React y contendrá lo que está dentro de las etiquetas de sus componentes (aquí<App name={name}/>
está dentroWrapper
, por lo que es elchildren
Tenga en cuenta que no necesariamente necesita usar
children
, que es único para un componente, y también puede usar accesorios normales si lo desea, o mezclar accesorios y niños:Esto es simple y está bien para muchos casos de uso, y lo recomendaría para la mayoría de las aplicaciones de consumo.
renderizar accesorios
Es posible pasar funciones de renderizado a un componente, este patrón generalmente se llama
render prop
, y elchildren
accesorio se usa a menudo para proporcionar esa devolución de llamada.Este patrón no está destinado realmente para el diseño. El componente contenedor generalmente se usa para mantener y administrar algún estado e inyectarlo en sus funciones de representación.
Ejemplo de contador:
Puede ser aún más elegante e incluso proporcionar un objeto
Tenga en cuenta que no necesariamente necesita usar
children
, es una cuestión de gusto / API.A partir de hoy, muchas bibliotecas están utilizando accesorios de renderizado (React context, React-motion, Apollo ...) porque las personas tienden a encontrar esta API más fácil que HOC. react-powerplug es una colección de componentes simples de render-prop. react-adopt te ayuda a hacer la composición.
Componentes de orden superior (HOC).
Un Componente / HOC de orden superior es generalmente una función que toma un componente y devuelve un nuevo componente.
Usar un componente de orden superior puede ser más eficaz que usar
children
orender props
, porque el contenedor puede tener la capacidad de cortocircuitar el renderizado un paso adelanteshouldComponentUpdate
.Aquí lo estamos usando
PureComponent
. Al volver a representar la aplicación, si elWrappedApp
nombre del accesorio no cambia con el tiempo, el contenedor tiene la capacidad de decir "No necesito renderizar porque los accesorios (en realidad, el nombre) son los mismos que antes". Con lachildren
solución basada arriba, incluso si la envoltura esPureComponent
, no es el caso porque el elemento hijo se recrea cada vez que se procesa el padre, lo que significa que la envoltura probablemente siempre se volverá a procesar, incluso si el componente envuelto es puro. Hay un complemento de babel que puede ayudar a mitigar esto y garantizar unchildren
elemento constante a lo largo del tiempo.Conclusión
Los componentes de orden superior pueden brindarle un mejor rendimiento. No es tan complicado, pero al principio parece poco amigable.
No migre toda su base de código a HOC después de leer esto. Solo recuerde que en las rutas críticas de su aplicación es posible que desee usar HOC en lugar de envoltorios de tiempo de ejecución por razones de rendimiento, particularmente si el mismo contenedor se usa muchas veces, vale la pena considerar convertirlo en un HOC.
Redux usó al principio un contenedor de tiempo de ejecución
<Connect>
y luego cambió a un HOCconnect(options)(Comp)
por razones de rendimiento (de manera predeterminada, el contenedor es puro y está en usoshouldComponentUpdate
). Esta es la ilustración perfecta de lo que quería resaltar en esta respuesta.Tenga en cuenta que si un componente tiene una API de render-prop, generalmente es fácil crear un HOC encima de él, por lo que si es un autor de lib, primero debe escribir una API de render prop y, finalmente, ofrecer una versión de HOC. Esto es lo que hace Apollo con el
<Query>
componente render-prop, y elgraphql
HOC que lo usa.Personalmente, uso ambos, pero en caso de duda prefiero los HOC porque:
compose(hoc1,hoc2)(Comp)
) en comparación con los accesorios de renderizadoNo dudo en usar / crear versiones HOC de mis herramientas favoritas:
Context.Consumer
reacciónSubscribe
graphql
HOC de Apollo en lugar deQuery
render propEn mi opinión, a veces los accesorios de render hacen que el código sea más legible, a veces menos ... Intento usar la solución más pragmática de acuerdo con las restricciones que tengo. A veces, la legibilidad es más importante que las actuaciones, a veces no. Elija sabiamente y no siga la tendencia de 2018 de convertir todo en accesorios de renderizado.
fuente
Además de la respuesta de Sophie, también he encontrado un uso en el envío de tipos de componentes secundarios, haciendo algo como esto:
fuente
delegate
, ¿cómo la encontraste?