Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add release jsx fragment blog post #345

Merged
merged 9 commits into from
Nov 28, 2017

Conversation

clemmy
Copy link
Contributor

@clemmy clemmy commented Nov 27, 2017

First draft of the blog post for the upcoming React v16.2 release.

Todos:

  • Ensure CRA release link is correct
  • Add a CodePen link for live demo

Do not merge yet!

@reactjs-bot
Copy link

reactjs-bot commented Nov 27, 2017

Deploy preview ready!

Built with commit cdde744

https://deploy-preview-345--reactjs.netlify.com

@clemmy clemmy closed this Nov 27, 2017
@clemmy clemmy reopened this Nov 27, 2017
@clemmy clemmy force-pushed the fragments-blog-post branch 2 times, most recently from b385743 to 3fbbbd0 Compare November 27, 2017 17:21

Unfortunately, support for Babel 6.x is not available, and there are currently no plans to back-port.

#### Typescript

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"TypeScript"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And the same for the below too

npm update typescript # for npm users
```

Also, editors may complain about errors in `.tsx` and `.js/.jsx` files using the new syntax. These errors can be safely ignored, or configured for [VS Code](https://code.visualstudio.com/Docs/languages/typescript#_using-newer-typescript-versions) and [Sublime Text](https://github.com/Microsoft/TypeScript-Sublime-Plugin/#note-using-different-versions-of-typescript).
Copy link
Contributor

@DanielRosenwasser DanielRosenwasser Nov 27, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about

These errors can be safely ignored, but editor support for JSX fragments are already available with updates for [Visual Studio 2015](https://www.microsoft.com/en-us/download/details.aspx?id=48593), [Visual Studio 2017](https://www.microsoft.com/en-us/download/details.aspx?id=55258), and [Sublime Text via Package Control](https://packagecontrol.io/packages/TypeScript).
Visual Studio Code will be updated soon, but [can be configured to use TypeScript 2.6.2 and later](https://code.visualstudio.com/Docs/languages/typescript#_using-newer-typescript-versions).


### Why Fragments?

When React released version 16, the ability to render an array of elements from a component's `render` method was added. This allowed developers to prevent extraneous markup with `div`s that pollute the HTML. However, it was inconvenient because every element in the array had to be explicitly keyed. Previously, in order to render an array of elements, the following code would be necessary:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When React released version 16, the ability to render an array of elements from a component's render method was added.

This reads a bit clumsy to me (too much passive voice!)

Maybe:

The React 16 release included the new ability to return an array from a component's render method.

?

}
```

However, the keys are only necessary for React's reconciliation algorithm when child elements are re-arranged and React needs to figure out which item in one render corresponds to in a subsequent render. If the array is static, then keys aren't necessary and only add extra noise to the code. So, let's omit them:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's be consistent about "rearrange" vs "re-arrange". I'd pick "rearrange" everywhere.

author: [clemmy]
---

Today, we're excited to bring the new `Fragment` export to React, which allows users to render **static** fragments without the unnecessary keying of each element in the fragment!
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This paragraph is slightly confusing because it doesn't mention the new syntax but shows the new syntax. Maybe:

Today, we’re excited to bring the new Fragment export to React, which allows users to render static fragments without the unnecessary keying of each element in the fragment!

render() {
 return (
   <React.Fragment>
     <li>Look ma</li>
     <li>no keys!</li>
   </React.Fragment>
 );
}

There is also a new short syntax for it that is already supported by some tools:

render() {
 return (
   <>
     <li>Look ma</li>
     <li>no keys!</li>
   </>
 );
}

Note that with the `<></>` syntax, attributes are not allowed to be passed. We made the decision to disallow attributes with fragments since they're semantically different from React elements. However, a fragment can be keyed by using the explicit fragment syntax:

```jsx
import { Fragment } from 'react';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we remove this and just use React.Fragment? Thinking about ES6 imports here adds unnecessary overhead to an already new concept.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sebmarkbage 's thought is that React.Fragment is quite long and will be harder to sell.


#### With Attributes and Keys

Note that with the `<></>` syntax, attributes are not allowed to be passed. We made the decision to disallow attributes with fragments since they're semantically different from React elements. However, a fragment can be keyed by using the explicit fragment syntax:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that with the <></> syntax, attributes are not allowed to be passed.

Maybe:

Note that the <></> syntax does not allow attributes on fragments.


Additionally, there is a [pragma option available in babel-plugin-transform-react-jsx](https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-react-jsx#pragmafrag) that allows the Babel compiler to de-sugar the `<>...</>` syntax to a custom identifier.

### Example Usages
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe just "Examples"?


Still, we are very thankful to the open source contributors who worked on solving this in the ecosystem.

Additionally, there is a [pragma option available in babel-plugin-transform-react-jsx](https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-react-jsx#pragmafrag) that allows the Babel compiler to de-sugar the `<>...</>` syntax to a custom identifier.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe replace "Additionally" with "If you use JSX with something other than React, " to better explain the context of this sentence.


As mentioned above, the most common way to use fragments in React is to simply use `<></>` tags. Generally, in the Javascript compiler phase of your build pipeline, the `<>...</>` will be de-sugared into a `createElement` call with `React.Fragment` as the type.

Take a look at the section on [How to Use it](#how-to-use-it) to see how to update your tooling to support JSX fragments.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is pretty confusing to me that this section is called "Example Usages" but there are no examples in it at all, and it asks me to follow to a different section. This breaks the flow. Can we avoid the jumps forward, and also rename this section if it doesn't actually contain examples?


### How to Use it

JSX fragments are still very new and some tools in the ecosystem may not be ready for it yet, so please be patient! However, we've tried our best to make it as simple as possible to upgrade from several popular toolchains:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"some tools" -> "many tools"? We worked with some folks, but "some tools" makes it sound like those who are lagging behind are responsible for it. It's a really new syntax, we shouldn't expect tool authors to handle it yet.


If you are using Babel with [Webpack](https://webpack.js.org/), then no additional steps need to be done because [babel-loader](https://github.com/babel/babel-loader) will be using your peer-installed version of Babel.

Unfortunately, support for Babel 6.x is not available, and there are currently no plans to back-port.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"to back-port" -> "to backport it" (I think that's a more common spelling)


#### Others

For other tools, please check with the corresponding documentation to check if there is support available. However, it's not a problem at all if you want the functionality of `<></>` without your linters and tooling complaining! You can always start with `<Fragment></Fragment>` and do a code-mod later to replace it with `<></>` when the appropriate support is available.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"code-mod" -> "codemod"

import React, { Fragment } from 'react';

items.map(item => (
<Fragment key="item.key">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be key={item.key} otherwise it has the same string key for all items.


Take a look at the section on [tooling support](#tooling-support) to see how to update your tooling to support JSX fragments.

#### With Attributes and Keys
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop the With. It's cleaner.

import React, { Fragment } from 'react';

render() {
// keys and commas are no longer needed
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// keys and commas are not needed in static JSX content

To be more precise?


render() {
// keys and commas are no longer needed
return <Fragment>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be in a parenthesis with this line on the second line so that the comparison to the syntax below is equivalent?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I'll update all the code blocks to have consistent styling with parentheses around JSX elements.

which allows users to render *static* fragments using familiar JSX element syntax.

```jsx
import React, { Fragment } from 'react';
Copy link
Member

@gaearon gaearon Nov 28, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would this work for TS users? AFAIK they have to enable a special mode to get React-as-a-default-export working. This is a thorny issue: facebook/react#11503. That's why I previously suggested to remove all imports from this blog post and just use React.Fragment. People will import React they way they already do, and there's no need to confuse them with a syntax that might not work.

Copy link
Member

@gaearon gaearon Nov 28, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It also doesn't match the Flow recommendation. Note they change default React import to a namespace import as part of conversion: https://flow.org/en/docs/react/components/. I just don't think we should confuse people with import syntax here. The blog post is not about it.

@acdlite acdlite force-pushed the fragments-blog-post branch from 5dec98c to 71b4765 Compare November 28, 2017 20:56
@acdlite acdlite force-pushed the fragments-blog-post branch from f5c3cac to 028b52d Compare November 28, 2017 21:46
@acdlite acdlite merged commit 0e3e124 into reactjs:master Nov 28, 2017

```bash
# for yarn users
yarn add eslint@3.x babel-eslint@7
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we suggesting to use a pretty old version of ESLint?

jhonmike pushed a commit to jhonmike/reactjs.org that referenced this pull request Jul 1, 2020
BetterZxx pushed a commit to BetterZxx/react.dev that referenced this pull request Mar 21, 2023
docs(en): merge reactjs.org into zh-hans @ 99b7901
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants