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