Learn how to use React Fragments let to group React elements, without requiring unnecessary markup or confusing key
props.
When working with React, there are times when you’ll want to pass around groups of React elements. And while it used to be that doing so required you to add useless container components or confusing arrays, React solved this last year by introducing Fragments — a simple way to group elements without adding any extra markup.
React.Fragment
— as used in the above example — is like a markupless component. When rendered to the DOM, its children will be rendered by themselves, making it possible to pass around groups of elements without introducing unnecessary markup. Fragments are also great for working with table and list markup (like the above), where it’s just not possible to add an extra <div>
.
<>Fragment syntax</>
After using fragments for a while, you may run into an eensy-weensy issue: typing out <React.Fragment>
is bothersome compared to typing <div>
. And while this won’t get in the way when fragments are truly necessary, it certainly can slow down adoption. Which is why, I suppose, fragments also come with a concise new syntax:
As you can see, the <>
and </>
tags in JSX now correspond to <React.Fragment>
and </React.Fragment>
. There’s nothing else special about them — they compile down to the same thing as any other React element, with a type
of React.Fragment
:
React.createElement(
React.Fragment,
null,
...childElements
)
When fragments were first released, there wasn’t much support for this syntax. But now that a year has passed, most major tools support it, including:
Of course, you don’t have to worry about any of this if you’re using create-react-app, because it has supported fragments from when they were first released!
Fragments have now had plenty of time for them to make their way into real world codebases. I’ve taken a look through a few open source projects to see how Fragments are being used in practice — and found a number of common use cases:
You can use fragments to create components that return a list of elements without wrapping them in a container or array. This is useful for components that return form and text markup — as wrapping the result in a container <div>
can cause headaches when styling things.
Spectrum's source frequently uses fragment-returning components for this purpose. For example, take a look at the e-mail confirmation component:
class UserEmailConfirmation extends React.Component {
render() {
const { emailError, email, isLoading } = this.state;
const { user } = this.props;
return (
<React.Fragment> <EmailForm
defaultValue={email}
loading={isLoading}
onChange={this.handleEmailChange}
onSubmit={this.init}
style={{ marginTop: '8px', marginBottom: '8px' }}
/>
{user.pendingEmail && (
<Notice>
A confirmation link was sent to {user.pendingEmail}. Click
the confirmation link and then return to this page. You can
resend the confirmation here, or enter a new email address.
</Notice>
)}
{emailError && <Error>{emailError}</Error>}
</React.Fragment> )
}
}
Similarly, you can use fragments to return groups of elements from render functions. Wordpress’ Calypso frontend frequently uses this pattern to inject a translate
function for internationalization:
<Step name="my-sites" target="my-sites" placement="below" arrow="top-left">
{ ( { translate } ) => (
<Fragment> <p>
{ translate(
"{{strong}}First things first.{{/strong}} Up here, you'll " +
"find tools for managing your site's content and design.",
{
components: {
strong: <strong />,
},
}
) }
</p>
<Continue click icon="my-sites" step="sidebar" target="my-sites" />
</Fragment> ) }
</Step>
Fragments make it far easier to conditionally render whole groups of elements without adding unnecessary markup. For example, they can be used with the ternary operator to switch an element’s content depending on the value of a prop:
export function ResetPasswordScreen({ hasPassword, name, ...formProps }) {
return (
<Layout>
{hasPassword ? (
<> <h3>Reset your password</h3>
<p>
To finish resetting your password, enter your new password
here and hit the "Reset" button.
</p>
</> ) : (
<> <h3>Hi {name}!</h3>
<p>Thanks for joining!</p>
<p>
Just one more step - please pick a password for your account:
</p>
</> )}
<ResetPasswordForm {...formProps} />
</Layout>
)
}
Fragments have one more powerful feature, which I’ve saved until last as it is rarely used. But when you do need this feature, it is invaluable:
Fragments can have key
props!
<React.Fragment key='somevalue'>
...
</React.Fragment>
Why would you want to give a Fragment a key? Well, it allows fragments to be used as items in arrays. Which in turn makes it possible to splice elements into text — and all without introducing any unnecessary markup.
For example, the console view in Frontend Armory’s Demoboard editor uses keyed fragments to replace newline characters with <br>
elements… and the resulting code is small enough that it would make for a great exercise!
See if you can use React Fragments to render the newline characters in the below string as <br>
tags, without introducing any extra markup.
Once you’ve given it a try, you can take a look at my solution by clicking the Solution tab at the bottom of the editor.
Thanks so much for reading! And if you know of any more uses for React Fragments, make sure to let everyone know in the twitter discussion!
Tokyo, Japan