{This.props.children} là gì và khi nào bạn nên sử dụng nó?


118

Là người mới bắt đầu làm quen với thế giới React, tôi muốn hiểu sâu hơn về những gì sẽ xảy ra khi tôi sử dụng {this.props.children}và những trường hợp sử dụng tương tự. Mức độ liên quan của nó trong đoạn mã dưới đây là gì?

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


1
Trong liên kết đã cho không rõ ràng rằng điều gì sẽ xảy ra khi tôi sử dụng {this.props.children} bên trong một thành phần.
Nimmy

Câu trả lời:


174

'Trẻ em' là gì?

Các tài liệu về React nói rằng bạn có thể sử dụng props.childrentrên các thành phần đại diện cho 'hộp chung' và không biết trước về con của chúng. Đối với tôi, điều đó không thực sự rõ ràng. Tôi chắc chắn đối với một số người, định nghĩa đó hoàn toàn hợp lý nhưng với tôi thì không.

Lời giải thích đơn giản của tôi về những gì this.props.childrenlàm được là nó được sử dụng để hiển thị bất cứ thứ gì bạn bao gồm giữa các thẻ mở và thẻ đóng khi gọi một thành phần.

Một ví dụ đơn giản:

Đây là một ví dụ về một hàm không trạng thái được sử dụng để tạo một thành phần. Một lần nữa, vì đây là một hàm, không có thistừ khóa nên chỉ cần sử dụngprops.children

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

Thành phần này chứa một thành phần <img>đang nhận một số propsvà sau đó nó sẽ hiển thị {props.children}.

Bất cứ khi nào thành phần này được gọi {props.children}cũng sẽ được hiển thị và đây chỉ là một tham chiếu đến những gì nằm giữa thẻ mở và thẻ đóng của thành phần.

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

Thay vì gọi thành phần bằng thẻ tự đóng <Picture />nếu bạn gọi thành phần đó sẽ có đầy đủ các thẻ đóng và mở, <Picture> </Picture>bạn có thể đặt thêm mã vào giữa nó.

Điều này loại bỏ các <Picture>thành phần khỏi nội dung của nó và làm cho nó có thể tái sử dụng nhiều hơn.

Tham khảo: Giới thiệu nhanh về các đạo cụ của React.children


Nếu không quan tâm đến khả năng tái sử dụng đối với các nút con, thì có sự khác biệt nào về hiệu suất khi gọi {props.children} từ thành phần con so với việc sử dụng nó bên trong thành phần con không?
Nimmy

1
@Nimmy khi sử dụng {props.children}, chúng tôi không gặp vấn đề về hiệu suất, chỉ cần thành phần được chuyển làm đạo cụ. và khi chúng ta có thể sử dụng trẻ em trong các thành phần con không cần phải sử dụng {props.children}
Soroush Chehresa

1
Ví dụ từ codeburst.io/…
Alpit Anand

1
@AlpitAnand Bạn có thể xem phần tham khảo ở cuối câu trả lời: |
Soroush Chehresa

1
Cảm ơn rất nhiều. Giải thích rất độc đáo.
Alok Ranjan

24

Tôi giả sử bạn đang nhìn thấy điều này trong renderphương thức của một thành phần React , như thế này (chỉnh sửa: câu hỏi đã chỉnh sửa của bạn thực sự hiển thị điều đó) :

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>

childrenlà một thuộc tính đặc biệt của các thành phần React chứa bất kỳ phần tử con nào được xác định trong thành phần, ví dụ như divsbên trong Exampleở trên. {this.props.children}bao gồm những đứa trẻ đó trong kết quả được hiển thị.

... các tình huống sử dụng giống nhau là gì

Bạn sẽ làm điều đó khi bạn muốn đưa các phần tử con vào đầu ra được hiển thị trực tiếp, không thay đổi; và không nếu bạn không.


Nếu không quan tâm đến khả năng tái sử dụng đối với các nút con, thì có sự khác biệt nào về hiệu suất khi gọi {props.children} từ thành phần con so với việc sử dụng nó bên trong thành phần con không?
Nimmy

@Nimmy: Tôi xin lỗi, tôi không hiểu ý bạn là * "... hơn là sử dụng nó bên trong thành phần con".
TJ Crowder

Ý tôi là "gọi {this.props.children} trong thành phần con hơn là viết các nút trực tiếp trong thành phần con tương ứng".
Nimmy

2
@Nimmy Tôi cho rằng bạn đang nghĩ tại sao tôi nên đặt {this.props.children} thay vì tôi có thể viết nó ra, tôi biết điều đó. Nếu đó là trường hợp, xin vui lòng làm điều đó và có một chút lợi thế về hiệu suất. Nhưng thành phần của bạn sẽ ở trạng thái tĩnh, nó không thể được sử dụng lại với tập hợp các phần tử con khác nhau ở một nơi khác trong cơ sở mã của bạn.
Subin Sebastian

2
@ssk: À! Tốt lắm. Nimmy - Có, bạn có thể viết trực tiếp những đứa trẻ trong của bạn render, nhưng chúng sẽ là những đứa trẻ giống nhau trong mọi trường hợp. Bằng cách chấp nhận các phần tử con (nếu thích hợp), mỗi trường hợp thành phần của bạn có thể có nội dung khác nhau. Tôi đã cập nhật ví dụ trong câu trả lời.
TJ Crowder

0

props.children đại diện cho nội dung giữa thẻ mở và thẻ đóng khi gọi / hiển thị một thành phần:

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

gọi / gọi / kết xuất Foo:

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

props and props.children

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.