Browse Source

Update fragment docs

main
Clement Hoang 7 years ago
parent
commit
a18bde67b2
  1. 172
      content/docs/fragments.md

172
content/docs/fragments.md

@ -4,9 +4,9 @@ title: Fragments
permalink: docs/fragments.html permalink: docs/fragments.html
--- ---
React fragments add improved support for returning multiple children from a component's render method. A common pattern in React is for a component to return multiple elements. React provides first-class `Fragment` support that lets you group a list of children without adding extra nodes to the DOM.
Fragments look like empty JSX tags. They let you group a list of children without adding extra nodes to the DOM: Fragments look like empty JSX tags:
```js ```js
render() { render() {
@ -20,124 +20,106 @@ render() {
} }
``` ```
### Live Demo
You can try out JSX fragment syntax with this [CodePen](https://codepen.io/reactjs/pen/VrEbjE?editors=1000).
## Motivation ## Motivation
A common pattern is for a component to return a list of children. Take this example HTML: A common pattern is for a component to return a list of children. Take this example React snippet:
```html ```jsx
Some text. class Table extends React.Component {
<h2>A heading</h2> render() {
More text. return (
<h2>Another heading</h2> <table>
Even more text. <tr>
<Columns />
</tr>
</table>
);
}
}
``` ```
Prior to version 16, the only way to achieve this in React was by wrapping the children in an extra element, usually a `div` or `span`: `<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.
```js ```jsx
render() { class Columns extends React.Component {
return ( render() {
// Extraneous div element :( return (
<div> <div>
Some text. <td>Hello</td>
<h2>A heading</h2> <td>World</td>
More text. </div>
<h2>Another heading</h2> );
Even more text. }
</div>
);
} }
``` ```
To address this limitation, React 16.0 added support for [returning an array of elements from a component's `render` method](https://reactjs.org/blog/2017/09/26/react-v16.0.html#new-render-return-types-fragments-and-strings). Instead of wrapping the children in a DOM element, you can put them into an array: results in a `<Table />` output of:
```jsx ```jsx
render() { <table>
return [ <tr>
"Some text.", <div>
<h2 key="heading-1">A heading</h2>, <td>Hello</td>
"More text.", <td>World</td>
<h2 key="heading-2">Another heading</h2>, </div>
"Even more text." </tr>
]; </table>
}
``` ```
However, this has some confusing differences from normal JSX: So, we introduce `Fragments`.
- Children in an array must be separated by commas.
- Children in an array must have a key to prevent React's [key warning](https://reactjs.org/docs/lists-and-keys.html#keys).
- Strings must be wrapped in quotes.
## Usage ## Usage
```jsx{4,7}
To provide a more consistent authoring experience for fragments, React now provides a first-class `Fragment` component that can be used in place of arrays. class Columns extends React.Component {
render() {
```jsx{3,9} return (
render() { <>
return ( <td>Hello</td>
<Fragment> <td>World</td>
Some text. </>
<h2>A heading</h2> );
More text. }
<h2>Another heading</h2>
Even more text.
</Fragment>
);
} }
``` ```
You can use `<Fragment />` the same way you'd use any other element, without changing the way you write JSX. No commas, no keys, no quotes. which results in a correct `<Table />` output of:
The Fragment component is available on the main React object:
```js ```jsx
const Fragment = React.Fragment; <table>
<tr>
<Fragment> <td>Hello</td>
<ChildA /> <td>World</td>
<ChildB /> </tr>
<ChildC /> </table>
</Fragment>
// This also works
<React.Fragment>
<ChildA />
<ChildB />
<ChildC />
</React.Fragment>
``` ```
### Shorthand You can use `<></>` the same way you'd use any other element.
Fragments are a common pattern in our codebases at Facebook. We anticipate they'll be widely adopted by other teams, too. To make the authoring experience as convenient as possible, we're adding syntactical support for fragments to JSX: ### Explicit Form
```jsx{3,9} Another way to use fragments is by using the `React.Fragment` component, which is available on the main React object.
render() { This may be necessary is your tooling doesn't support JSX fragments yet.
return ( Note that in React, `<></>` desugars to `<React.Fragment/>`.
<>
Some text. ```jsx{4,7}
<h2>A heading</h2> class Columns extends React.Component {
More text. render() {
<h2>Another heading</h2> return (
Even more text. <React.Fragment>
</> <td>Hello</td>
); <td>World</td>
</React.Fragment>
);
}
} }
``` ```
In React, this desugars to a `<React.Fragment/>` element, as in the example from the previous section. (Non-React frameworks that use JSX may compile to something different.)
### Keyed Fragments ### Keyed Fragments
Note that the `<></>` syntax does not accept attributes, including keys. The `<></>` syntax does not accept keys nor attributes.
If you need a keyed fragment, you can use `<Fragment />` directly. A use case for this is mapping a collection to an array of fragments -- for example, to create a description list: 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 ```jsx
function Glossary(props) { function Glossary(props) {
@ -145,14 +127,18 @@ function Glossary(props) {
<dl> <dl>
{props.items.map(item => ( {props.items.map(item => (
// Without the `key`, React will fire a key warning // Without the `key`, React will fire a key warning
<Fragment key={item.id}> <React.Fragment key={item.id}>
<dt>{item.term}</dt> <dt>{item.term}</dt>
<dd>{item.description}</dd> <dd>{item.description}</dd>
</Fragment> </React.Fragment>
))} ))}
</dl> </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. `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…
Cancel
Save