React v16.2.0:Fragments

1. 什麼是 Fragments?

Fragments 大概長這樣:

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

2. 為什麼使用 Fragments?

有時候我們需要使用如下代碼片段:

Some text.n<h2>A heading</h2>nMore text.n<h2>Another heading</h2>nEven more text.n

在 React 16 之前的版本中,沒法直接將以上代碼作為組件的 children 使用的。我們需要把以上代碼外面包裹一個 div 或者 span。

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

在 React 16.0 中已經支持了在組件中渲染數組。

  • 相關鏈接: returning an array of elements from a components render method.

於是我們可以這麼寫:

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

但是這個寫法和直接使用 JSX 還是有不同的:

  1. 每個子元素需要使用逗號分隔
  2. 數組的每一項必須要有 key 值,否則會產生警告
  3. 字元串必須使用引號

而在最新的 React 版本中引入了 Fragment 組件。

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

Fragment 是 React 對象的屬性。

我們可以這麼使用:

const Fragment = React.Fragment;nn<Fragment>n <ChildA />n <ChildB />n <ChildC />n</Fragment>n

或者這樣使用:

<React.Fragment>n <ChildA />n <ChildB />n <ChildC />n</React.Fragment> n

3. JSX Fragment Syntax

同樣的,jsx 也增加了對 fragment 的支持。

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

當編譯時,<> 被轉化為 <React.Fragment/>。(在非 React 框架下使用 jsx 會被以不同的方式編譯為對應的代碼)

4. Keyed Fragments

有一點是需要注意的,<></> 並不接受任何屬性,包括 key 屬性。

如果我們需要使用有 key 值的 Fragment 那麼只能使用 <Fragment /> 組件。

function Glossary(props) {n return (n <dl>n {props.items.map(item => (n // 如果沒有 `key`, React 會觸發一個警告n <Fragment key={item.id}>n <dt>{item.term}</dt>n <dd>{item.description}</dd>n </Fragment>n )}n </dl>n );n}n

Fragment 只有唯一的一個屬性:key。

5. 使用 Fragment 語法

大部分最新版的工具都已經支持了 Fragment 語法,如果不支持的話,可以去給該工具提 issue。

babel 7 已經支持了 Fragment 語法。plugin-transform-react-jsx 插件已經可以轉換 <></> 代碼。

如果在 React 中使用,只需要把 preset-react 升級到最新版:

# for yarn usersnyarn upgrade @babel/core @babel/preset-reactn# for npm usersnnpm update @babel/core @babel/preset-reactn

最新版的 TypeScript、ESLint、Flow、Prettier 都已經支持了 Fragment。


React 交流群:

  • React技術交流1群(已滿)
  • React技術交流2群 450586076

推薦閱讀:

實戰 | 用原生js寫一個"多動症"的簡歷
前端周刊第42期
2017 年 9 月:15 個有趣的 JS 和 CSS 庫

TAG:React | JSX | 前端框架 |