diff --git a/beta/src/content/apis/react/Fragment.md b/beta/src/content/apis/react/Fragment.md index b85fbaee..d43d59d6 100644 --- a/beta/src/content/apis/react/Fragment.md +++ b/beta/src/content/apis/react/Fragment.md @@ -1,24 +1,18 @@ --- -title: React.Fragment +title: Fragment (<>...) --- -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 ( - <> - - - - ); -} +```js +<> + + + ``` -`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. - @@ -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 ( + <> + + + + ); +} ``` -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 `

` and `

` DOM nodes appear as siblings without wrappers around them: + + + +```js +export default function Blog() { return ( <> - - + + + ) +} + +function Post({ title, body }) { + return ( + <> + + + + ); +} + +function PostTitle({ title }) { + return

{title}

+} + +function PostBody({ body }) { + return ( +
+

{body}

+
); } ``` -You usually use `Fragment` with a special syntax, the empty JSX tag `<>`, that is equivalent to writing ``. + -### Assigning multiple elements to a variable {/*assigning-multiple-elements-to-a-variable*/} + + +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 ( + + + + + ); +} ``` + +Usually you won't need this unless you need to [pass a `key` to your `Fragment`.](#rendering-a-list-of-fragments) + + + +### 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 => + + + + + ); +} ``` -function BlogPosts(posts) { - return posts.map(() => - - {post.title} - - + +You can inspect the DOM to verify that there are no wrapper elements around the Fragment children: + + + +```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 => + + + + + ); +} + +function PostTitle({ title }) { + return

{title}

+} + +function PostBody({ body }) { + return ( +
+

{body}

+
); } ``` +
+ ## Reference {/*reference*/} -### `React.Fragment` {/*react-fragment*/} +### `Fragment` {/*fragment*/} + +Wrap elements in `` 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 `` in most cases. + +#### Props {/*fragment-props*/} + +- **optional** `key`: Fragments declared with the explicit `` 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 `...`. -Wrap elements in `` 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 `` in most cases. +- React does not [reset state](/learn/preserving-and-resetting-state) when you go from rendering `<>` to `[]` or back, or when you go from rendering `<>` to `` and back. This only works a single level deep: for example, going from `<><>` to `` resets the state. See the precise semantics [here.](https://gist.github.com/clemmy/b3ef00f9507909429d8aa0d3ee4f986b) -#### Props {/*reference-props*/} -- **optional** `key`: Fragments declared with the explicit `` syntax may have [keys.](https://beta.reactjs.org/learn/rendering-lists#keeping-list-items-in-order-with-key) diff --git a/beta/src/content/learn/rendering-lists.md b/beta/src/content/learn/rendering-lists.md index c94a9358..25539028 100644 --- a/beta/src/content/learn/rendering-lists.md +++ b/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 `
`, or use the slightly longer and more explicit `` 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 `
`, or use the slightly longer and [more explicit `` 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 `
` and `

...

`. However, the `<> ` shorthand syntax doesn't support passing keys, so you'd have to write `` explicitly: +Alternatively, you could render a collection of fragments which contain `
` and `

...

`. However, the `<>...` shorthand syntax doesn't support passing keys, so you'd have to write `` explicitly: diff --git a/beta/src/content/learn/writing-markup-with-jsx.md b/beta/src/content/learn/writing-markup-with-jsx.md index 84cbd40d..c4390421 100644 --- a/beta/src/content/learn/writing-markup-with-jsx.md +++ b/beta/src/content/learn/writing-markup-with-jsx.md @@ -169,11 +169,11 @@ If you don't want to add an extra `
` 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. -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. diff --git a/beta/src/sidebarReference.json b/beta/src/sidebarReference.json index b1a7a3a0..6ad502fb 100644 --- a/beta/src/sidebarReference.json +++ b/beta/src/sidebarReference.json @@ -51,7 +51,7 @@ "wip": true }, { - "title": "Fragment", + "title": "Fragment (<>...)", "path": "/apis/react/Fragment" }, {