Andrew Clark
7 years ago
committed by
GitHub
4 changed files with 179 additions and 4 deletions
@ -0,0 +1,144 @@ |
|||
--- |
|||
id: fragments |
|||
title: Fragments |
|||
permalink: docs/fragments.html |
|||
--- |
|||
|
|||
A common pattern in React is for a component to return multiple elements. Fragments let you group a list of children without adding extra nodes to the DOM. |
|||
|
|||
Fragments look like empty JSX tags: |
|||
|
|||
```js |
|||
render() { |
|||
return ( |
|||
<> |
|||
<ChildA /> |
|||
<ChildB /> |
|||
<ChildC /> |
|||
</> |
|||
); |
|||
} |
|||
``` |
|||
|
|||
## Motivation |
|||
|
|||
A common pattern is for a component to return a list of children. Take this example React snippet: |
|||
|
|||
```jsx |
|||
class Table extends React.Component { |
|||
render() { |
|||
return ( |
|||
<table> |
|||
<tr> |
|||
<Columns /> |
|||
</tr> |
|||
</table> |
|||
); |
|||
} |
|||
} |
|||
``` |
|||
|
|||
`<Columns />` would need to return multiple `<td>` elements in order for the rendered HTML to be valid. If a parent div was used inside the `render()` of `<Columns />`, then the resulting HTML will be invalid. |
|||
|
|||
```jsx |
|||
class Columns extends React.Component { |
|||
render() { |
|||
return ( |
|||
<div> |
|||
<td>Hello</td> |
|||
<td>World</td> |
|||
</div> |
|||
); |
|||
} |
|||
} |
|||
``` |
|||
|
|||
results in a `<Table />` output of: |
|||
|
|||
```jsx |
|||
<table> |
|||
<tr> |
|||
<div> |
|||
<td>Hello</td> |
|||
<td>World</td> |
|||
</div> |
|||
</tr> |
|||
</table> |
|||
``` |
|||
|
|||
So, we introduce `Fragments`. |
|||
|
|||
## Usage |
|||
|
|||
```jsx{4,7} |
|||
class Columns extends React.Component { |
|||
render() { |
|||
return ( |
|||
<> |
|||
<td>Hello</td> |
|||
<td>World</td> |
|||
</> |
|||
); |
|||
} |
|||
} |
|||
``` |
|||
|
|||
which results in a correct `<Table />` output of: |
|||
|
|||
```jsx |
|||
<table> |
|||
<tr> |
|||
<td>Hello</td> |
|||
<td>World</td> |
|||
</tr> |
|||
</table> |
|||
``` |
|||
|
|||
You can use `<></>` the same way you'd use any other element. |
|||
|
|||
### Explicit Form |
|||
|
|||
Another way to use fragments is by using the `React.Fragment` component, which is available on the main React object. |
|||
This may be necessary is your tooling doesn't support JSX fragments yet. |
|||
Note that in React, `<></>` desugars to `<React.Fragment/>`. |
|||
|
|||
```jsx{4,7} |
|||
class Columns extends React.Component { |
|||
render() { |
|||
return ( |
|||
<React.Fragment> |
|||
<td>Hello</td> |
|||
<td>World</td> |
|||
</React.Fragment> |
|||
); |
|||
} |
|||
} |
|||
``` |
|||
|
|||
### Keyed Fragments |
|||
|
|||
The `<></>` syntax does not accept keys nor attributes. |
|||
|
|||
If you need a keyed fragment, you can use `<React.Fragment />` directly. A use case for this is mapping a collection to an array of fragments -- for example, to create a description list: |
|||
|
|||
```jsx |
|||
function Glossary(props) { |
|||
return ( |
|||
<dl> |
|||
{props.items.map(item => ( |
|||
// Without the `key`, React will fire a key warning |
|||
<React.Fragment key={item.id}> |
|||
<dt>{item.term}</dt> |
|||
<dd>{item.description}</dd> |
|||
</React.Fragment> |
|||
))} |
|||
</dl> |
|||
); |
|||
} |
|||
``` |
|||
|
|||
`key` is the only attribute that can be passed to `Fragment`. In the future, we may add support for additional attributes, such as event handlers. |
|||
|
|||
### Live Demo |
|||
|
|||
You can try out JSX fragment syntax with this [CodePen](https://codepen.io/reactjs/pen/VrEbjE?editors=1000). |
Loading…
Reference in new issue