Що таке {this.props.children} і коли ви повинні ним користуватися?


118

Будучи початківцем у реагуванні світу, я хочу глибоко зрозуміти, що відбувається, коли я використовую, {this.props.children}і які ситуації використовувати для того ж. Яка відповідність у наведеному нижче фрагменті коду?

render() {
  if (this.props.appLoaded) {
    return (
      <div>
        <Header
          appName={this.props.appName}
          currentUser={this.props.currentUser}
        />
        {this.props.children}
      </div>
    );
  }
}


1
По даному посиланню було не ясно, що відбувається, коли я використовую {this.props.children} всередині компонента.
Німмі

Відповіді:


176

Що навіть "діти"?

Документи React кажуть, що ви можете використовувати props.childrenдля компонентів, які представляють "загальні коробки" і які не знають своїх дітей достроково. Для мене це не дуже зрозуміло. Я впевнений, що для деяких це визначення має ідеальний сенс, але це не було для мене.

Моє просте пояснення того, що this.props.childrenробить, це те, що воно використовується для відображення того, що ви включаєте між тегами, що відкриваються та закриваються, при виклику компонента.

Простий приклад:

Ось приклад функції без стану, яка використовується для створення компонента. Знову ж таки, оскільки це функція, thisключового слова немає, тому просто використовуйтеprops.children

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

Цей компонент містить <img>те, що отримує деякі, propsа потім воно відображається {props.children}.

Щоразу, коли цей компонент викликається {props.children}, також буде відображатися, і це лише посилання на те, що знаходиться між відкриваючими та закривальними тегами компонента.

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

Замість виклику компонента з тегом, що самозакривається, <Picture />якщо ви викликаєте його, він буде повним відкриттям та закриттям тегів, <Picture> </Picture>ви можете розмістити більше коду між ним.

Це відключає <Picture>компонент від його вмісту і робить його більш багаторазовим.

Довідка: Швидке вступ до реквізиту React's діти


Якщо повторне використання не стосується дочірніх вузлів, чи є різниця в продуктивності при виклику {props.children} з дочірнього компонента, ніж його використання всередині дочірнього компонента?
Німмі

1
@Nimmy при використанні {props.children} у нас немає проблеми з продуктивністю, просто потрібен пройдений компонент як реквізит. і коли ми можемо використовувати дітей всередині дочірнього компонента, не потрібно використовувати {props.children}
Соруш Чехреса

1
Приклад з codeburst.io/…
Alpit Anand

1
@AlpitAnand Посилання можна побачити в кінці відповіді: |
Сорош Чехреса

1
Дуже дякую. Дуже красиво пояснено.
Алок Ранджан

24

Я припускаю, що ви бачите це в renderметоді компонента React , як ось цей (редагувати: ваше відредаговане запитання дійсно показує це) :

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>

childrenє особливою властивістю компонентів React, яка містить будь-які дочірні елементи, визначені всередині компонента, наприклад, divsвсередині Exampleвище. {this.props.children}включає тих дітей у виведений результат.

... які ситуації використовувати те саме

Ви б це зробили, коли хочете включити дочірні елементи у виведений результат безпосередньо, без змін; а не, якщо ви цього не зробили.


Якщо повторне використання не стосується дочірніх вузлів, чи є різниця в продуктивності при виклику {props.children} з дочірнього компонента, ніж його використання всередині дочірнього компонента?
Німмі

@Nimmy: Вибачте, я не знаю, що ви маєте на увазі під "" ... ніж використовувати його всередині дочірнього компонента ".
TJ Crowder

Я мав на увазі "виклик {this.props.children} у дочірньому компоненті, ніж запис вузлів безпосередньо у відповідний дочірній компонент".
Німмі

2
@ Nimmy Я припускаю, що ти думаєш, навіщо мені ставити {this.props.children} замість цього, я можу це записати, я це знаю. Якщо це так, будь ласка, зробіть це і майте невелику перевагу у виконанні. Але ваш компонент буде статичним, його неможливо повторно використовувати з набором різних дітей у іншому місці вашої кодової бази.
Субін Себастьян

2
@ssk: Ах! Хороший. Німмі - Так, ви можете записати дітей прямо у свій render, але вони були б однаковими дітьми у кожному випадку. Приймаючи дочірні елементи (де це доречно), кожен екземпляр вашого компонента може мати різний вміст. Я оновив приклад у відповіді.
TJ Crowder

0

props.children представляє вміст між тегами, що відкриваються та закриваються, при виклику / візуалізації компонента:

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

викликати / зателефонувати / візуалізувати Foo:

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

реквізит і реквізит. діти

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.