Tại sao các mảnh trong React 16 tốt hơn div div?


165

Trong React 16.2, hỗ trợ cải tiến Fragmentsđã được thêm vào. Thông tin thêm có thể được tìm thấy trên bài đăng trên blog của React ở đây.

Chúng ta đều quen thuộc với mã sau đây:

render() {
  return (
    // Extraneous div element :(
    <div>
      Some text.
      <h2>A heading</h2>
      More text.
      <h2>Another heading</h2>
      Even more text.
    </div>
  );
}

Vâng, chúng tôi cần một div container, nhưng nó không phải là vấn đề lớn.

Trong React 16.2, chúng ta có thể làm điều này để tránh div container xung quanh:

render() {
  return (
    <Fragment>
      Some text.
      <h2>A heading</h2>
      More text.
      <h2>Another heading</h2>
      Even more text.
    </Fragment>
  );
}

Trong cả hai trường hợp, chúng ta vẫn cần một phần tử container bao quanh các phần tử bên trong.

Câu hỏi của tôi là, tại sao sử dụng một Fragmentthích hợp hơn? Nó có giúp với hiệu suất? Nếu vậy, tại sao? Sẽ yêu một cái nhìn sâu sắc.


2
Tôi thấy nó thực sự hữu ích cho việc tạo kiểu flexbox khi tạo trẻ cấp một cho cha mẹ
willwoo

32
Vấn đề divlà bạn không luôn muốn có một phần tử trình bao bọc. Các phần tử Wrapper có một ý nghĩa và thông thường bạn cần các kiểu bổ sung cho ý nghĩa đó được loại bỏ. <Fragment>chỉ là cú pháp đường mà không được kết xuất. Có những tình huống khi tạo một trình bao bọc rất khó khăn, ví dụ trong SVG, nơi <div>không thể được sử dụng và <group>không phải lúc nào cũng như bạn muốn.
Sulthan

Câu trả lời:


305
  1. Nó nhanh hơn một chút và sử dụng ít bộ nhớ hơn (không cần tạo thêm nút DOM). Điều này chỉ có lợi ích thực sự trên những cây rất lớn và / hoặc sâu, nhưng hiệu suất ứng dụng thường bị chết bởi hàng ngàn vết cắt. Đây là một cắt ít hơn.
  2. Một số cơ chế CSS như Flexbox và CSS Grid có mối quan hệ cha-con đặc biệt và việc thêm divs ở giữa khiến bạn khó giữ bố cục mong muốn trong khi trích xuất các thành phần logic.
  3. Thanh tra DOM ít lộn xộn hơn. :-)

Bạn có thể tìm thấy các mô tả về một số trường hợp sử dụng khác trong vấn đề Phản ứng này: Thêm API phân đoạn để cho phép trả về nhiều thành phần từ kết xuất


24
4. Viết danh sách định nghĩa <dt><dd>dễ dàng hơn nhiều. Trở lại các yếu tố ghép đôi là khó xử trước đây Fragments.
Sonson123

Do Fragment hoạt động trong phản ứng-bản địa? Tôi đã cố gắng để import Fragment from 'react'. Nhưng nó không được xác định trong RN.
binchik

3
Đối với number 2, bảng đã thực sự là vấn đề lớn nhất đối với chúng tôi. Cấu trúc cần thiết của table>tr>td(có thể có theadvà tương tự) được tạo cho một số mã React khó xử.
Matsemann

2
@binchik đã thử import {Fragment} from 'react'chưa? đó là một xuất khẩu có tên.
Soska

1
Số 3 là quan trọng nhất!
Zach Smith

28

Thêm vào tất cả các câu trả lời ở trên có một lợi thế nữa: khả năng đọc mã , Fragmentthành phần hỗ trợ một dạng đường cú pháp , <>. Do đó, mã trong câu hỏi của bạn có thể được viết dễ dàng hơn như:

render() {
  return (
    <>
      Some text.
      <h2>A heading</h2>
      More text.
      <h2>Another heading</h2>
      Even more text.
    </>
  );
}

Theo tài liệu ,

Trong React, desugars này cho một <React.Fragment/>phần tử, như trong ví dụ từ phần trước. (Các khung công tác không phản ứng sử dụng JSX có thể biên dịch thành thứ gì đó khác.)

Không lộn xộn, phải không?

Lưu ý rằng bạn vẫn cần sử dụng <Fragment>cú pháp nếu bạn cần cung cấp keycho đoạn.


Cú pháp ngắn hơn này hiện chưa được hỗ trợ trong ứng dụng tạo phản ứng. Tham khảo: Reacjs.org/docs/fragments.html#short-syntax
codingsplash

2
@codingsplash CRA 2.0 có ngay bây giờ.
Gặp Zaveri

1
Không thể chịu được đoạn đường cú pháp này, nó có vẻ vô tình và truyền tải ít ý nghĩa vốn có. Rất thích<Fragment>
ESR

3
@ESR cá nhân tôi thích nó. Nghĩ theo cách này. Những đứa trẻ được bao bọc trong không có gì, giống như không có gì trong <>. Vô hình.
dùng3614030

6
  • Đã thêm các tính năng trước đây với JSX
  • Đánh dấu ngữ nghĩa jsx tốt hơn. Các yếu tố bao bọc được sử dụng khi cần thiết không phải vì chúng bị ép buộc.
  • Đánh dấu dom tổng thể ít hơn (tăng hiệu suất kết xuất và ít chi phí bộ nhớ hơn)

Nó đơn giản như khi bạn không cần một yếu tố bao bọc, bạn không bị buộc phải sử dụng một yếu tố. Có ít phần tử là tuyệt vời nhưng tôi nghĩ lợi ích lớn nhất là có thể hiển thị các phần tử trong jsx mà trước đây không thể có và thêm ý nghĩa ngữ nghĩa tốt hơn cho các phần tử trình bao bởi vì bây giờ chúng là tùy chọn.

Điều này là không thể trước đây:

 <select>
    {this.renderOptions()}
 </select>

Liếc nhìn vào phần sau trong Phản ứng 15, bạn không thể biết liệu phần tử trình bao có cần thiết hay không:

<span>
  <h1>Hello</h1>
  {this.getContent()}
</span>

2

Theo tài liệu Reacjs.org, các nhu cầu quan trọng nhất <Fragment> </Fragment>thay vì div là để tránh phá vỡ ngữ nghĩa HTML. Khi chúng tôi sử dụng div thay vì <Fragment> </Fragment>chúng tôi phá vỡ ngữ nghĩa HTML.

Để biết thêm về ngữ nghĩa html. vui lòng nhấp vào và cũng có trường hợp nếu bạn sử dụng div thay vì Fragment thì đó sẽ là html không hợp lệ, ví dụ: hãy xem mã này:

class Columns extends React.Component {
  render() {
    return (
      <div>
        <td>Hello</td>
        <td>World</td>
      </div>
    );
  }
}

<table>
      <tr>
        <div>
          <td>Hello</td>
          <td>World</td>
        </div>
      </tr>
 </table>

Những mảnh vỡ giải quyết vấn đề này.


1
  1. Khi sử dụng <React.Fragment>...</React.Fragment>, chúng ta có thể thêm thẻ cha vào các phần tử JSX mà không cần thêm nút bổ sung vào DOM.
  2. bạn có thể thay thế các thẻ div phụ bằng React.Fragment
  3. viết React.Fragment mỗi lần là quá dài đối với bạn. React.Fragment có cú pháp tốc ký mà bạn có thể sử dụng. Nó là<>...</>.
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.