Co to jest {this.props.children} i kiedy należy go używać?

118

Będąc początkującym w świecie React, chcę dogłębnie zrozumieć, co się dzieje, gdy używam {this.props.children}i jakie są sytuacje , w których mogę tego samego użyć. Jakie jest jego znaczenie w poniższym fragmencie kodu?

render() {
  if (this.props.appLoaded) {
    return (
      <div>
        <Header
          appName={this.props.appName}
          currentUser={this.props.currentUser}
        />
        {this.props.children}
      </div>
    );
  }
}
Nimmy
źródło
3
Możliwy duplikat ReactJS: Po co używać this.props.children?
maazadeeb
1
W podanym linku nie było jasne, co się dzieje, gdy używam {this.props.children} wewnątrz komponentu.
Nimmy
Best Resource mxstbr.blog/2017/02/react-children-deepdive
Akshay Vijay Jain

Odpowiedzi:

177

Czym w ogóle są „dzieci”?

Dokumentacja Reacta mówi, że można używać props.childrenna komponentach, które reprezentują „ogólne pudełka” i które nie znają swoich dzieci z wyprzedzeniem. Dla mnie to nie wyjaśniło sprawy. Jestem pewien, że dla niektórych ta definicja ma sens, ale nie dla mnie.

Moje proste wyjaśnienie tego, co this.props.childrenrobi, jest takie, że jest używany do wyświetlania wszystkiego, co umieścisz między otwierającym i zamykającym tagiem podczas wywoływania komponentu.

Prosty przykład:

Oto przykład funkcji bezstanowej, która jest używana do tworzenia składnika. Ponownie, ponieważ jest to funkcja, nie ma thissłowa kluczowego, więc po prostu użyjprops.children

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

Ten składnik zawiera element, <img>który odbiera, propsa następnie jest wyświetlany {props.children}.

Za każdym razem, gdy ten składnik jest wywoływany, {props.children}zostanie również wyświetlony i jest to tylko odniesienie do tego, co znajduje się między otwierającym i zamykającym znacznikiem komponentu.

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

Zamiast wywoływać komponent z samozamykającym się tagiem, <Picture />jeśli wywołasz go, spowoduje to całkowite otwarcie i zamknięcie znaczników <Picture> </Picture>, możesz następnie umieścić między nim więcej kodu.

Powoduje to odłączenie <Picture>komponentu od jego zawartości i sprawia, że ​​jest on łatwiejszy do ponownego wykorzystania.

Odniesienie: Szybkie wprowadzenie do rekwizytów Reacta. Dzieci

Soroush Chehresa
źródło
Jeśli ponowne użycie nie dotyczy węzłów potomnych, czy jest jakaś różnica w wydajności podczas wywoływania {props.children} z komponentu podrzędnego niż używanie go wewnątrz komponentu potomnego?
Nimmy
1
@Nimmy podczas korzystania z {props.children} nie mamy problemu z wydajnością, wystarczy, że przekazujemy komponent jako rekwizyty. i kiedy możemy za pomocą dzieciom wewnątrz komponentu dziecko nie trzeba używać {props.children}
Soroush Chehresa
1
Przykład pochodzi z codeburst.io/…
Alpit Anand
1
@AlpitAnand Na końcu odpowiedzi możesz zobaczyć odniesienie: |
Soroush Chehresa
1
Wielkie dzięki. Bardzo ładnie wyjaśnione.
Alok Ranjan
24

Zakładam, że widzisz to w rendermetodzie komponentu Reacta , na przykład (edycja: Twoje edytowane pytanie rzeczywiście to pokazuje) :

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>

childrento specjalna właściwość komponentów Reacta, która zawiera dowolne elementy potomne zdefiniowane w komponencie, np. divswnętrze Examplepowyżej. {this.props.children}uwzględnia te elementy podrzędne w renderowanym wyniku.

... jakie są sytuacje, aby użyć tego samego

Zrobiłbyś to, gdybyś chciał bezpośrednio dołączyć elementy potomne do renderowanego wyjścia, bez zmian; a nie jeśli nie.

TJ Crowder
źródło
Jeśli ponowne użycie nie dotyczy węzłów potomnych, czy jest jakaś różnica w wydajności podczas wywoływania {props.children} z komponentu podrzędnego niż używanie go wewnątrz komponentu potomnego?
Nimmy,
@Nimmy: Przepraszam, nie wiem, co masz na myśli przez * "... niż użycie tego w komponencie potomnym".
TJ Crowder
Miałem na myśli „wywołanie {this.props.children} w komponencie podrzędnym niż pisanie węzłów bezpośrednio w odpowiednim komponencie potomnym”.
Nimmy,
2
@Nimmy Zakładam, że zastanawiasz się, dlaczego powinienem umieścić {this.props.children} zamiast tego mogę to zapisać, wiem o tym. Jeśli tak jest, zrób to i miej niewielką przewagę w wydajności. Ale twój komponent będzie statyczny, nie można go ponownie wykorzystać z zestawem różnych elementów podrzędnych w innym miejscu w bazie kodu.
Subin Sebastian
2
@ssk: Ach! Niezłe. Nimmy - Tak, możesz napisać do dzieci bezpośrednio w swoim render, ale w każdym przypadku będą to te same dzieci. Akceptując elementy podrzędne (w stosownych przypadkach), każde wystąpienie komponentu może mieć inną zawartość. Zaktualizowałem przykład w odpowiedzi.
TJ Crowder
0

props.children reprezentuje zawartość między otwierającym i zamykającym tagiem podczas wywoływania / renderowania komponentu:

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

invoke / call / render Foo:

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

rekwizyty i rekwizyty. dzieci

zeljko_a
źródło