Что такое {this.props.children} и когда его следует использовать?

118

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

render() {
  if (this.props.appLoaded) {
    return (
      <div>
        <Header
          appName={this.props.appName}
          currentUser={this.props.currentUser}
        />
        {this.props.children}
      </div>
    );
  }
}
Nimmy
источник
3
Возможный дубликат ReactJS: зачем использовать this.props.children?
maazadeeb
1
В данной ссылке не было ясно, что происходит, когда я использую {this.props.children} внутри компонента.
Нимми
Лучший ресурс mxstbr.blog/2017/02/react-children-deepdive
Акшай Виджай Джайн

Ответы:

177

Что вообще такое «дети»?

В документации 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>компонент от его содержимого и делает его более пригодным для повторного использования.

Ссылка: краткое введение в props.children React

Соруш Чехреза
источник
Если повторное использование не касается дочерних узлов, есть ли разница в производительности при вызове {props.children} из дочернего компонента, чем при его использовании внутри дочернего компонента?
Нимми
1
@Nimmy при использовании {props.children} у нас нет проблем с производительностью, просто нужно передать компонент в качестве реквизита. и когда мы можем использовать дочерние элементы внутри дочернего компонента, не нужно использовать {props.children}
Соруш Чехреза,
1
Пример взят
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}включает эти дочерние элементы в визуализированный результат.

... в каких ситуациях можно использовать то же самое

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

TJ Crowder
источник
Если повторное использование не касается дочерних узлов, есть ли разница в производительности при вызове {props.children} из дочернего компонента, чем при его использовании внутри дочернего компонента?
Нимми
@ Нимми: Извините, я не понимаю, что вы имеете в виду под * "... чем использовать его внутри дочернего компонента".
TJ Crowder
Я имел в виду «вызов {this.props.children} в дочернем компоненте, а не запись узлов непосредственно в соответствующий дочерний компонент».
Нимми
2
@ Нимми Полагаю, вы думаете, почему я должен поставить {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>

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

zeljko_a
источник