¿Qué es {this.props.children} y cuándo debería usarlo?

118

Siendo un principiante en el mundo React, quiero comprender en profundidad qué sucede cuando uso {this.props.children}y cuáles son las situaciones para usar el mismo. ¿Cuál es su relevancia en el siguiente fragmento de código?

render() {
  if (this.props.appLoaded) {
    return (
      <div>
        <Header
          appName={this.props.appName}
          currentUser={this.props.currentUser}
        />
        {this.props.children}
      </div>
    );
  }
}
Nimmy
fuente
3
Posible duplicado de ReactJS: ¿Por qué usar this.props.children?
maazadeeb
1
No estaba claro en el enlace dado qué sucede cuando uso {this.props.children} dentro de un componente.
Nimmy
Best Resource mxstbr.blog/2017/02/react-children-deepdive
Akshay Vijay Jain

Respuestas:

175

¿Qué son incluso 'niños'?

Los documentos de React dicen que puede usar props.childrenen componentes que representan 'cajas genéricas' y que no conocen a sus hijos antes de tiempo. Para mí, eso realmente no aclaró las cosas. Estoy seguro de que para algunos, esa definición tiene mucho sentido, pero para mí no.

Mi explicación simple de lo que this.props.childrenhace es que se usa para mostrar todo lo que incluye entre las etiquetas de apertura y cierre al invocar un componente.

Un simple ejemplo:

A continuación, se muestra un ejemplo de una función sin estado que se utiliza para crear un componente. Nuevamente, dado que esta es una función, no hay una thispalabra clave, así que solo useprops.children

const Picture = (props) => {
  return (
    <div>
      <img src={props.src}/>
      {props.children}
    </div>
  )
}

Este componente contiene un <img>que está recibiendo algo propsy luego se muestra {props.children}.

Siempre que se invoque este componente {props.children}, también se mostrará y esto es solo una referencia a lo que hay entre las etiquetas de apertura y cierre del componente.

//App.js
render () {
  return (
    <div className='container'>
      <Picture key={picture.id} src={picture.src}>
          //what is placed here is passed as props.children  
      </Picture>
    </div>
  )
}

En lugar de invocar el componente con una etiqueta de cierre automático, <Picture />si lo invoca con etiquetas de apertura y cierre completas <Picture> </Picture>, puede colocar más código entre ellas.

Esto desacopla el <Picture>componente de su contenido y lo hace más reutilizable.

Referencia: Una introducción rápida a los accesorios de React.

Soroush Chehresa
fuente
Si la reutilización no se refiere a los nodos secundarios, ¿hay alguna diferencia de rendimiento al llamar a {props.children} desde el componente secundario que al usarlo dentro del componente secundario?
Nimmy
1
@Nimmy cuando usamos {props.children} no tenemos problemas de rendimiento, solo necesitamos el componente pasado como accesorios. y cuando podemos usar niños dentro del componente secundario, no es necesario usar {props.children}
Soroush Chehresa
1
El ejemplo es de codeburst.io/…
Alpit Anand
1
@AlpitAnand Puede ver la referencia al final de la respuesta: |
Soroush Chehresa
1
Muchas gracias. Muy bien explicado.
Alok Ranjan hace
24

Supongo que está viendo esto en el rendermétodo de un componente React , como este (editar: su pregunta editada realmente muestra eso) :

class Example extends React.Component {
  render() {
    return <div>
      <div>Children ({this.props.children.length}):</div>
      {this.props.children}
    </div>;
  }
}

class Widget extends React.Component {
  render() {
    return <div>
      <div>First <code>Example</code>:</div>
      <Example>
        <div>1</div>
        <div>2</div>
        <div>3</div>
      </Example>
      <div>Second <code>Example</code> with different children:</div>
      <Example>
        <div>A</div>
        <div>B</div>
      </Example>
    </div>;
  }
}

ReactDOM.render(
  <Widget/>,
  document.getElementById("root")
);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

childrenes una propiedad especial de los componentes de React que contiene cualquier elemento hijo definido dentro del componente, por ejemplo, el divsinterior de Examplearriba. {this.props.children}incluye a esos niños en el resultado renderizado.

... cuales son las situaciones para usar el mismo

Lo haría cuando desee incluir los elementos secundarios en la salida renderizada directamente, sin cambios; y no si no lo hiciste.

TJ Crowder
fuente
Si la reutilización no se refiere a los nodos secundarios, ¿hay alguna diferencia de rendimiento al llamar a {props.children} desde el componente secundario que al usarlo dentro del componente secundario?
Nimmy
@Nimmy: Lo siento, no sé qué quieres decir con * "... que usarlo dentro del componente secundario".
TJ Crowder
Me refiero a "llamar a {this.props.children} en el componente secundario que escribir los nodos directamente en el componente secundario correspondiente".
Nimmy
2
@Nimmy Supongo que estás pensando por qué debería poner {this.props.children} en su lugar. Puedo escribirlo, lo sé. Si ese es el caso, hágalo y obtenga una ligera ventaja en el rendimiento. Pero su componente será estático, no se puede reutilizar con un conjunto de hijos diferentes en un lugar diferente en su base de código.
Subin Sebastian
2
@ssk: ¡Ah! Buena esa. Nimmy: Sí, podrías escribir los niños directamente en tu render, pero serían los mismos niños en todos los casos. Al aceptar elementos secundarios (cuando corresponda), cada instancia de su componente puede tener un contenido diferente. Actualicé el ejemplo en la respuesta.
TJ Crowder
0

props.children representa el contenido entre las etiquetas de apertura y cierre al invocar / renderizar un componente:

const Foo = props => (
  <div>
    <p>I'm {Foo.name}</p>
    <p>abc is: {props.abc}</p>

    <p>I have {props.children.length} children.</p>
    <p>They are: {props.children}.</p>
    <p>{Array.isArray(props.children) ? 'My kids are an array.' : ''}</p>
  </div>
);

const Baz = () => <span>{Baz.name} and</span>;
const Bar = () => <span> {Bar.name}</span>;

invocar / llamar / renderizar Foo:

<Foo abc={123}>
  <Baz />
  <Bar />
</Foo>

utilería y utilería infantil

zeljko_a
fuente