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 還是有不同的:
- 每個子元素需要使用逗號分隔
- 數組的每一項必須要有 key 值,否則會產生警告
- 字元串必須使用引號
而在最新的 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 庫