Qu'est-ce que {this.props.children} et quand faut-il l'utiliser?

118

Étant un débutant dans le monde React, je veux comprendre en profondeur ce qui se passe lorsque j'utilise {this.props.children}et quelles sont les situations pour l'utiliser. Quelle est la pertinence de celui-ci dans l'extrait de code ci-dessous?

render() {
  if (this.props.appLoaded) {
    return (
      <div>
        <Header
          appName={this.props.appName}
          currentUser={this.props.currentUser}
        />
        {this.props.children}
      </div>
    );
  }
}
Nimmy
la source
3
Copie
maazadeeb
1
Il n'était pas clair dans le lien donné que ce qui se passe lorsque j'utilise {this.props.children} à l'intérieur d'un composant.
Nimmy
Meilleure ressource mxstbr.blog/2017/02/react-children-deepdive
Akshay Vijay Jain

Réponses:

177

Qu'est-ce que même les «enfants»?

La documentation React indique que vous pouvez utiliser des props.childrencomposants qui représentent des «boîtes génériques» et qui ne connaissent pas leurs enfants à l'avance. Pour moi, cela n'a pas vraiment clarifié les choses. Je suis sûr que pour certains, cette définition est parfaitement logique, mais ce n'était pas le cas pour moi.

Mon explication simple de ce que this.props.childrenfait est qu'il est utilisé pour afficher tout ce que vous incluez entre les balises d'ouverture et de fermeture lors de l'appel d'un composant.

Un exemple simple:

Voici un exemple de fonction sans état utilisée pour créer un composant. Encore une fois, puisqu'il s'agit d'une fonction, il n'y a pas de thismot-clé, alors utilisez simplementprops.children

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

Ce composant contient un <img>qui en reçoit propspuis il s'affiche {props.children}.

Chaque fois que ce composant est appelé {props.children}sera également affiché et il ne s'agit que d'une référence à ce qui se trouve entre les balises d'ouverture et de fermeture du composant.

//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>
  )
}

Au lieu d'appeler le composant avec une balise à fermeture automatique, <Picture />si vous l'invoquez, <Picture> </Picture>vous pouvez alors placer plus de code entre les balises d'ouverture et de fermeture complètes .

Cela dissocie le <Picture>composant de son contenu et le rend plus réutilisable.

Référence: Une introduction rapide aux accessoires de React.

Soroush Chehresa
la source
Si la réutilisabilité n'est pas concernée pour les nœuds enfants, y a-t-il une différence de performances lors de l'appel de {props.children} à partir du composant enfant par rapport à son utilisation à l'intérieur du composant enfant?
Nimmy
1
@Nimmy lorsque vous utilisez {props.children}, nous n'avons pas de problème de performances, nous avons juste besoin d'un composant passé comme accessoire. et quand nous pouvons utiliser des enfants dans le composant enfant, nous n'avons pas besoin d'utiliser {props.children}
Soroush Chehresa
1
L'exemple vient de codeburst.io
Alpit Anand
1
@AlpitAnand Vous pouvez voir la référence à la fin de la réponse: |
Soroush Chehresa
1
Merci beaucoup. Très bien expliqué.
Alok Ranjan
24

Je suppose que vous voyez cela dans la renderméthode d' un composant React , comme ceci (modifier: votre question modifiée le montre bien) :

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>

childrenest une propriété spéciale des composants React qui contient tous les éléments enfants définis dans le composant, par exemple l' divsintérieur Exampleci-dessus. {this.props.children}inclut ces enfants dans le résultat rendu.

... quelles sont les situations pour utiliser le même

Vous le feriez lorsque vous souhaitez inclure les éléments enfants dans la sortie rendue directement, inchangés; et pas si vous ne l'avez pas fait.

TJ Crowder
la source
Si la réutilisabilité n'est pas concernée pour les nœuds enfants, y a-t-il une différence de performances lors de l'appel de {props.children} à partir du composant enfant par rapport à son utilisation à l'intérieur du composant enfant?
Nimmy
@Nimmy: Je suis désolé, je ne sais pas ce que vous entendez par * "... que de l'utiliser dans le composant enfant".
TJ Crowder
Je voulais dire "appeler {this.props.children} dans le composant enfant plutôt qu'écrire les nœuds directement dans le composant enfant respectif".
Nimmy
2
@Nimmy Je suppose que vous vous demandez pourquoi devrais-je mettre {this.props.children} à la place, je peux l'écrire, je le sais. Si tel est le cas, veuillez le faire et avoir un léger avantage en termes de performances. Mais votre composant sera statique, il ne peut pas être réutilisé avec un ensemble d'enfants différents à un endroit différent dans votre base de code.
Subin Sebastian
2
@ssk: Ah! Joli. Nimmy - Oui, vous pourriez écrire les enfants directement dans votre render, mais ce seraient les mêmes enfants dans tous les cas. En acceptant les éléments enfants (le cas échéant), chaque instance de votre composant peut avoir un contenu différent. J'ai mis à jour l'exemple dans la réponse.
TJ Crowder
0

props.children représente le contenu entre les balises d'ouverture et de fermeture lors de l'appel / du rendu d'un composant:

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>;

invoquer / appeler / rendre Foo:

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

accessoires et accessoires enfants

zeljko_a
la source