12/08/2018, 16:33

React 16.2.0 Hỗ trợ cải tiến cho Fragments

React 16.2 hiện đã khả dụng ! Bổ sung lớn nhất là cải thiện hỗ trợ cho việc trả lại nhiều children từ phương pháp render của component mà không cần phải bao đóng trong thẻ DIV(cuối cùng nó cũng được các nhà phát triển react thực hiện). Nó được gọi các phần này là fragments: Fragments trông giống ...

React 16.2 hiện đã khả dụng ! Bổ sung lớn nhất là cải thiện hỗ trợ cho việc trả lại nhiều children từ phương pháp render của component mà không cần phải bao đóng trong thẻ DIV(cuối cùng nó cũng được các nhà phát triển react thực hiện). Nó được gọi các phần này là fragments: Fragments trông giống như các thẻ JSX rỗng. Tính năng mới thú vị này được thực hiện bằng cách thêm vào cả React và JSX.

render() {
  return (
    <>
      <ChildA />
      <ChildB />
      <ChildC />
    </>
  );
}

Một trong những trường hợp phổ khi làm việc với React là hiển thị những elements con có cùng cấp như sau :

Some text.
<h2>A heading</h2>
More text.
<h2>Another heading</h2>
Even more text.

Với React phiên bản trước 16.0, bắt buộc hàm render phải trả về một DOM element. Do đó chúng ta thường phải tạo thêm một thẻ bao đóng DIV hay SPAN.

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

Để giải quyết hạn chế này, React 16.0 đã thêm hỗ trợ để trả về một mảng các phần tử từ phương thức render của component. Thay vì gói các con trong một phần tử DOM, bạn có thể đặt chúng vào một mảng:

render() {
 return [
  "Some text.",
  <h2 key="heading-1">A heading</h2>,
  "More text.",
  <h2 key="heading-2">Another heading</h2>,
  "Even more text."
 ];
}

Dẫu vậy cách làm này vẫn có những hạn chế như:

  • Các phần tử văn bản trong mảng phải được đặt vào dấu nháy
  • Các phần tử con phải có thuộc tính key nếu không muốn bị React “sửa lưng”
  • Giữa các phần tử phải được phân cách bởi dấu phẩy

Nhóm phát triển React đã giới thiệu component Fragment để thay thế cho mảng. Bằng cách sử dụng Fragment, lập trình viên có thể dùng như một thẻ bao đóng, do đó không cần dấy phẩy, key, dấu nháy.

const Fragment = React.Fragment;

<Fragment>
  <ChildA />
  <ChildB />
  <ChildC />
</Fragment>

// This also works
<React.Fragment>
  <ChildA />
  <ChildB />
  <ChildC />
</React.Fragment>

bằng việc khai báo thêm React.Fragment

Trong React, điều này dẫn đến một phần tử <React.Fragment />, như trong ví dụ từ section trước. (Các framework non-react sử dụng JSX có thể biên dịch thành một cái gì đó khác.) Cú pháp flagment trong JSX được lấy cảm hứng từ các kỹ thuật đã biết như nhà xây dựng XMLList () <> </> trong E4X. Sử dụng một cặp thẻ rỗng để biểu diễn ý tưởng nó sẽ không thêm một phần tử thực vào DOM.

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

Lưu ý rằng <> </> cú pháp không chấp nhận các thuộc tính, bao gồm cả keys. Nếu bạn cần một đoạn mã, bạn có thể sử dụng <Fragment /> trực tiếp. Một trường hợp sử dụng cho việc này là mapping collection cho một mảng các đoạn - ví dụ: để tạo một danh sách mô tả:

function Glossary(props) {
  return (
    <dl>
      {props.items.map(item => (
        // Without the `key`, React will fire a key warning
        <Fragment key={item.id}>
          <dt>{item.term}</dt>
          <dd>{item.description}</dd>
        </Fragment>
      )}
    </dl>
  );
}

Tại thời điểm hiện tại, key là thuộc tính duy nhất Fragment có thể nhận. Trong tương lai có thể sẽ được hỗ trợ thêm các thuộc tính khác, chẳng hạn như các hàm xử lý sự kiện. Demo

Create React App

Thử nghiệm hỗ trợ cho cú pháp của Fragment sẽ được thêm vào Create React App trong vài ngày tới. Hỗ trợ hoàn chỉnh có lẽ cần nhiều thời gian hơn để hoàn thiện.

Babel

Hỗ trợ cho JSX fragment đã có mặt trong Babel v7.0.0-beta.31. Nếu bạn đang dùng Babel 7, chỉ cần cập nhật Babel lên phiên bản mới nhất và plugin của nó.

yarn upgrade @babel/core @babel/plugin-transform-react-jsx

npm update @babel/core @babel/plugin-transform-react-jsx

Hoặc nếu bạn dùng react preset.

yarn upgrade @babel/core @babel/preset-react

npm update @babel/core @babel/preset-react

Rất tiếc chưa có kế hoạch hỗ trợ fragment cho Babel 6, và có khả năng sẽ không có.

webpack và babel-loader

Bạn chỉ cần cập nhật Babel 7 là được rồi.

TypeScript

TypeScript đã hỗ trợ cú pháp fragment trong phiên bản 2.6.2.

yarn upgrade typescript

npm update typescript

Flow

Flow hỗ trợ cú pháp JSX fragment trong phiên bản 0.59.

yarn upgrade flow-bin

npm update flow-bin

Prettier

Prettier sẽ hỗ trợ fragment trong phiên bản 1.9 sắp ra mắt.

ESLint

JSX fragment được hỗ trợ bởi ESLint 3.x khi được dùng chung với babel-eslint:

yarn add eslint@3.x babel-eslint@7

npm install eslint@3.x babel-eslint@7

// hoặc bạn có thể update
yarn upgrade eslint@3.x babel-eslint@7

npm update eslint@3.x babel-eslint@7

Đừng quên thêm dòng sau vào .babelrc:

"parser": "babel-eslint"

Tóm lại

Fragment không phải là thay đổi quá lớn trong React, nhưng có thể giải quyết vấn đề rất thường gặp trong React: trả về nhiều children cùng cấp.

Bạn có thể cài đặt React 16.2.0 bằng:

yarn add react@^16.2.0 react-dom@^16.2.0

npm install --save react@^16.2.0 react-dom@^16.2.0

hoặc dùng CDN:

<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>

Nguồn : https://reactjs.org/blog/2017/11/28/react-v16.2.0-fragment-support.html

0