Browse Source

[Beta] Fragment edits (#5067)

* [Beta] Fragment edits

* Add some links
main
dan 3 years ago
committed by GitHub
parent
commit
651d31ff6f
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 161
      beta/src/content/apis/react/Fragment.md
  2. 4
      beta/src/content/learn/rendering-lists.md
  3. 4
      beta/src/content/learn/writing-markup-with-jsx.md
  4. 2
      beta/src/sidebarReference.json

161
beta/src/content/apis/react/Fragment.md

@ -1,24 +1,18 @@
---
title: React.Fragment
title: Fragment (<>...</>)
---
<Intro>
The `React.Fragment` component, which can be used with a special `<></>` syntax, lets you use multiple elements in place of one, without wrapping them in any other container element:
The `Fragment` component, which is often used via the `<>...</>` syntax, lets you render multiple elements in place of one, without wrapping them in any other container element.
```
function Component() {
return (
<>
<OneChild />
<AnotherChild />
</>
);
}
```js
<>
<OneChild />
<AnotherChild />
</>
```
`Fragment` is useful because grouping elements with `Fragment` has no effect on layout or styles, unlike if you wrapped the elements in some other container such as a DOM element.
</Intro>
<InlineToc />
@ -29,26 +23,83 @@ function Component() {
### Returning multiple elements {/*returning-multiple-elements*/}
Use `Fragment` to group multiple elements together. You can use it to put multiple elements in any place where a single element can go. For example, a component can only return one element, but by using `Fragment` you can group multiple elements together and then return them as a group:
Use `Fragment`, or the equivalent `<>...</>` syntax, to group multiple elements together. You can use it to put multiple elements in any place where a single element can go. For example, a component can only return one element, but by using a Fragment you can group multiple elements together and then return them as a group:
```js {3,6}
function Post() {
return (
<>
<PostTitle />
<PostBody />
</>
);
}
```
function Notification() {
Fragments are useful because grouping elements with a Fragment has no effect on layout or styles, unlike if you wrapped the elements in some other container such as a DOM element. If you inspect this example with the browser tools, you'll see that all `<h1>` and `<p>` DOM nodes appear as siblings without wrappers around them:
<Sandpack>
```js
export default function Blog() {
return (
<>
<NotificationTitle />
<NotificationBody />
<Post title="An update" body="It's been a while since I posted..." />
<Post title="My new blog" body="I am starting a new blog!" />
</>
)
}
function Post({ title, body }) {
return (
<>
<PostTitle title={title} />
<PostBody body={body} />
</>
);
}
function PostTitle({ title }) {
return <h1>{title}</h1>
}
function PostBody({ body }) {
return (
<article>
<p>{body}</p>
</article>
);
}
```
You usually use `Fragment` with a special syntax, the empty JSX tag `<></>`, that is equivalent to writing `<React.Fragment></React.Fragment>`.
</Sandpack>
### Assigning multiple elements to a variable {/*assigning-multiple-elements-to-a-variable*/}
<DeepDive title="How to write a Fragment without the special syntax?">
The example above is equivalent to importing `Fragment` from React:
Like any other element, you can assign `Fragment` elements to variables, pass them as props, and so on:
```js {1,5,8}
import { Fragment } from 'react';
function Post() {
return (
<Fragment>
<PostTitle />
<PostBody />
</Fragment>
);
}
```
Usually you won't need this unless you need to [pass a `key` to your `Fragment`.](#rendering-a-list-of-fragments)
</DeepDive>
### Assigning multiple elements to a variable {/*assigning-multiple-elements-to-a-variable*/}
Like any other element, you can assign Fragment elements to variables, pass them as props, and so on:
```js
function CloseDialog() {
const buttons = (
<>
@ -68,8 +119,8 @@ function CloseDialog() {
You can use `Fragment` to group text together with components:
```
function DateRangePicker({start, end}) {
```js
function DateRangePicker({ start, end }) {
return (
<>
From
@ -83,25 +134,69 @@ function DateRangePicker({start, end}) {
### Rendering a list of Fragments {/*rendering-a-list-of-fragments*/}
Here's a situation where you need to write `React.Fragment` explicitly instead of using the `<></>` syntax: When you [render multiple elements in a loop](/learn/rendering-lists), you need to assign a `key` to each element. If the elements within the loop are Fragments, you need to use the normal JSX element syntax in order to provide the `key` attribute:
Here's a situation where you need to write `Fragment` explicitly instead of using the `<></>` syntax. When you [render multiple elements in a loop](/learn/rendering-lists), you need to assign a `key` to each element. If the elements within the loop are Fragments, you need to use the normal JSX element syntax in order to provide the `key` attribute:
```js {3,6}
function Blog() {
return posts.map(post =>
<Fragment key={post.id}>
<PostTitle title={post.title} />
<PostBody body={post.body} />
</Fragment>
);
}
```
function BlogPosts(posts) {
return posts.map(() =>
<React.Fragment key={post.id}>
<Heading>{post.title}</Heading>
<BlogPostBody post={post} />
</React.Fragment>
You can inspect the DOM to verify that there are no wrapper elements around the Fragment children:
<Sandpack>
```js
import { Fragment } from 'react';
const posts = [
{ id: 1, title: 'An update', body: "It's been a while since I posted..." },
{ id: 2, title: 'My new blog', body: 'I am starting a new blog!' }
];
export default function Blog() {
return posts.map(post =>
<Fragment key={post.id}>
<PostTitle title={post.title} />
<PostBody body={post.body} />
</Fragment>
);
}
function PostTitle({ title }) {
return <h1>{title}</h1>
}
function PostBody({ body }) {
return (
<article>
<p>{body}</p>
</article>
);
}
```
</Sandpack>
## Reference {/*reference*/}
### `React.Fragment` {/*react-fragment*/}
### `Fragment` {/*fragment*/}
Wrap elements in `<Fragment>` to group them together in situations where you need a single element. Grouping elements in `Fragment` has no effect on the resulting DOM; it is the same as if the elements were not grouped. The empty JSX tag `<></>` is shorthand for `<Fragment></Fragment>` in most cases.
#### Props {/*fragment-props*/}
- **optional** `key`: Fragments declared with the explicit `<Fragment>` syntax may have [keys.](https://beta.reactjs.org/learn/rendering-lists#keeping-list-items-in-order-with-key)
#### Caveats {/*caveats*/}
- If you want to pass `key` to a Fragment, you can't use the `<>...</>` syntax. You have to explicitly import `Fragment` from `'react'` and render `<Fragment key={yourKey}>...</Fragment>`.
Wrap elements in `<React.Fragment>` to group them together in situations where you need a single element. Grouping elements in `Fragment` has no effect on the resulting DOM; it is the same as if the elements were not grouped. The empty JSX tag `<></>` is shorthand for `<React.Fragment></React.Fragment>` in most cases.
- React does not [reset state](/learn/preserving-and-resetting-state) when you go from rendering `<><Child /></>` to `[<Child />]` or back, or when you go from rendering `<><Child /></>` to `<Child />` and back. This only works a single level deep: for example, going from `<><><Child /></></>` to `<Child />` resets the state. See the precise semantics [here.](https://gist.github.com/clemmy/b3ef00f9507909429d8aa0d3ee4f986b)
#### Props {/*reference-props*/}
- **optional** `key`: Fragments declared with the explicit `<React.Fragment>` syntax may have [keys.](https://beta.reactjs.org/learn/rendering-lists#keeping-list-items-in-order-with-key)

4
beta/src/content/learn/rendering-lists.md

@ -376,7 +376,7 @@ img { width: 100px; height: 100px; border-radius: 50%; }
What do you do when each item needs to render not one, but several DOM nodes?
The short `<> </>` fragment syntax won't let you pass a key, so you need to either group them into a single `<div>`, or use the slightly longer and more explicit `<Fragment>` syntax:
The short [`<>...</>` Fragment](/apis/react/Fragment) syntax won't let you pass a key, so you need to either group them into a single `<div>`, or use the slightly longer and [more explicit `<Fragment>` syntax:](/apis/react/Fragment#rendering-a-list-of-fragments)
```js
import { Fragment } from 'react';
@ -1206,7 +1206,7 @@ hr {
Using the original line index as a `key` doesn't work anymore because each separator and paragraph are now in the same array. However, you can give each of them a distinct key using a suffix, e.g. `key={i + '-text'}`.
Alternatively, you could render a collection of fragments which contain `<hr />` and `<p>...</p>`. However, the `<> </>` shorthand syntax doesn't support passing keys, so you'd have to write `<Fragment>` explicitly:
Alternatively, you could render a collection of fragments which contain `<hr />` and `<p>...</p>`. However, the `<>...</>` shorthand syntax doesn't support passing keys, so you'd have to write `<Fragment>` explicitly:
<Sandpack>

4
beta/src/content/learn/writing-markup-with-jsx.md

@ -169,11 +169,11 @@ If you don't want to add an extra `<div>` to your markup, you can write `<>` and
</>
```
This empty tag is called a *[React fragment.](/apis/react/Fragment)* React fragments let you group things without leaving any trace in the browser HTML tree.
This empty tag is called a *[Fragment.](/apis/react/Fragment)* Fragments let you group things without leaving any trace in the browser HTML tree.
<DeepDive title="Why do multiple JSX tags need to be wrapped?">
JSX looks like HTML, but under the hood it is transformed into plain JavaScript objects. You can't return two objects from a function without wrapping them into an array. This explains why you also can't return two JSX tags without wrapping them into another tag or a fragment.
JSX looks like HTML, but under the hood it is transformed into plain JavaScript objects. You can't return two objects from a function without wrapping them into an array. This explains why you also can't return two JSX tags without wrapping them into another tag or a Fragment.
</DeepDive>

2
beta/src/sidebarReference.json

@ -51,7 +51,7 @@
"wip": true
},
{
"title": "Fragment",
"title": "Fragment (<>...</>)",
"path": "/apis/react/Fragment"
},
{

Loading…
Cancel
Save