
React v16.2.0: Improved Support for Fragments - hswolff
https://reactjs.org/blog/2017/11/28/react-v16.2.0-fragment-support.html
======
acemarke
Several people had already noted [0] that you could implement equivalent
behavior by using a component that simply returns its own children:

    
    
        const Fragment = ({children}) => children;
        
        // later
        return <Fragment><Component1 /><Component2 /></Fragment>;
    

Nice to see this added as both a built-in component type and a useful syntax
extension. (Now if they'd just modify JSX syntax so that we can pass props by
matching local variable names similar to how ES6 object literals work, like
`<SomeComponent a b c />`, rather than having that become a defaulted-true
boolean, I'd be happy :) )

[0] [https://medium.com/@gajus/using-react-v16-to-create-self-
des...](https://medium.com/@gajus/using-react-v16-to-create-self-destructing-
components-de8e4eb61d0f)

~~~
danabramov
To be pedantic, it's not 100% equivalent. You can find the nitty-gritty
details about the (intentional) differences here:
[https://github.com/facebook/react/pull/10783](https://github.com/facebook/react/pull/10783).

We did mention the author of react-aux in the blog post though :-)

> _Thanks to Gajus Kuizinas and other contributors who prototyped the Fragment
> component in open source._

------
ojosilva
Ive started with React recently and strangely the lack of fragments were one
of the things that caught my attention in the first days.

Another thing I'm looking for in React as I get started is better styling
support. I'm resourcing to React JSS for that, but I feel it should be part of
the language. The _web trinity_ if you may is HTML-CSS-JS and React basically
left CSS out half-baked into almost unusable style attributes, so I still have
to resource to className and CSS. Or am I just being noob-anal?

~~~
worldsayshi
I've found styled components to be a nice attempt at bundling styles with the
component. Haven't tried that many options though.

It has out of the box support in Atom and scss (like?) syntax.

[https://github.com/styled-components/styled-
components](https://github.com/styled-components/styled-components)

------
hobofan
I appreciate the addition of Fragments, but I'm not sure if the addition to
the JSX syntax was really a good decision.

While it initially took some time to wrap my head around JSX (especially with
a lot of JS mixed into it), after that I really started to enjoy JSX for its
simplicity. The Fragment syntax adds some additional magic to JSX (which is
rarely a good thing), and will also very likely break all the syntax
highlighting out there again when used.

~~~
acdlite
> The Fragment syntax adds some additional magic to JSX (which is rarely a
> good thing)

In: <></>

Out: <React.Fragment></React.Fragment>

WITCHCRAFT!! SORCERY!!

Teasing aside, I don't get what's magical about this. It's a straightforward
transform. You can call that "magic," I'll call it "syntax."

~~~
hobofan
Sure, we can call it syntax. Of course, for anyone who already knows what it
does, it's just a transform, but the problem with extra syntax is that it
makes it harder for newcomers to pick it up.

Taking your example when putting it in front of someone seeing it for the
first time:

In: <></>

Out (Newcomer): WTF does that mean? Did someone forget to put something in
those tags?

~~~
danabramov
Same newcomer, in a couple of weeks: "Don't know how I lived without it".

I understand your point, but in practice people love tiny affordances like
this, especially when they are needed as often as fragments are.

This is a balance, but it's important to consider the needs of power users
too. Beginners don't stay beginners forever. We've thought about this for a
few months, and decided that adding syntax would be better. I understand some
people will always disagree though, and that's fine :-)

~~~
electric_sheep
Yeah, it seems like the decision to make the fragment a first-class JSX
concept has a lot to do with portability between renderers. The post makes it
clear you all have given this a lot of thought and care, and I appreciate that
(even if it _will_ take me awhile to get used to seeing empty tags, haha).

------
slaymaker1907
These will be quite nice when wrapping things like css grid components which
must be on the same DOM level.

------
yladiz
Man, although fragments are a pretty useful concept, the implementation is
really terrible. It feels so uninspired and without thought of the design, in
my opinion. They could have chosen some character instead of an empty tag and
it would have been much better, like an asterisk[1], because it would be clear
that the tag serves a defined purpose. I would almost argue that if this weird
shorthand is necessary to accomplish this task (something that irked me when
creating text heavy pages) then JSX should be redesigned to handle it natively
without the weird fragment syntax.

1: Like this:

    
    
      <*> ... </*>

~~~
danabramov
>feels so uninspired and without thought of the design, in my opinion.

Thanks for feedback! I assure there wasn't a lack of thought, in fact we
discussed this for several weeks before even beginning to implement this. Your
proposal was also considered but it doesn't bring anything over <>, whereas *
already has a meaning in JS related to generators. It would be confusing to
use it here for a different purpose.

FYI, <> is not original. As mentioned in the post, it has prior art. It
already went through standardization once (in E4X). It has also been used for
months (maybe over a year) in ReasonML, and its users reported really enjoying
this syntax.

You may not like it but it doesn't mean we haven't given this any thought. :-)

~~~
yladiz
Yes, technically if the empty tags do suffice, then the asterisk brings no
additional value, and it would be potentially confusing to use a character
that already serves a purpose in Javascript, although I doubt it since JSX
tags don't support generators as an attribute or name. You could replace the
asterisk with a different character in that case. My main point is that the
empty tag feels, well, empty and made without a real purpose, in part because
it's just so foreign compared to HTML (which is what JSX is based on?) as this
kind of thing is never found in HTML. While I'm sure that there wasn't a lot
of discussion within the React team about this, the inclusion of at least a
single character, whatever that would be, would make it feel like it was
actually designed properly, and I would also argue that adding something to
make the tag feel nonempty would actually have a value (to make the tag
explicit and not confusing).

I don't necessarily buy the prior art arguments too because E4X was barely
used even though it was a standard and is now deprecated, and ReasonML is
pretty specialized and much less popular, as well as has a different set of
users, than React. If you had told me a product in the same category as React,
like Angular, Vue, Ember, Ractive, etc., used that syntax, I would be much
more receptive.

~~~
danabramov
_> I doubt it since JSX tags don't support generators as an attribute or name_

Not currently, but we do have some plans regarding do-expressions, generators,
and JSX. So * might get a meaning, even though not in attributes but children.

 _> My main point is that the empty tag feels, well, empty and made without a
real purpose, in part because it's just so foreign compared to HTML (which is
what JSX is based on?) as this kind of thing is never found in HTML._

I think most React users in practice don't touch HTML that often. JSX has
quite a few differences with HTML, and we don't really plan to bring it
_closer_ to HTML in the future. It is more important to us to make JSX
pleasant and convenient to everyday React users than it is to have 1:1 mapping
to every HTML concept.

 _> ReasonML is pretty specialized and much less popular, as well as has a
different set of users, than React._

I would argue that people using ReasonML today are the same kind of early
adopters (and often even the same people) that started using React four years
ago when the ecosystem didn't exist (and shaped that ecosystem). I trust their
judgment.

 _> If you had told me a product in the same category as React, like Angular,
Vue, Ember, Ractive, etc., used that syntax, I would be much more receptive_

By that logic, we could dismiss React when it came out, because it was not
like anything else :-) Give this syntax some time. It felt odd to me at first,
after living with it for a few months it feels very natural. I'm sure you'll
get to like it eventually too. At that point it might feel odd that other
libraries _don 't_ provide this syntax.

------
KeitIG
I love to see these small improvements added to React.

Everything is not perfect though, some issues have been here for a looong
time. At the moment, my biggest problem is the non-support of passive events
[0]. And today, some browsers are starting to make some events passive by
default (`touchmove` on Chrome for example), it is quietly starting to become
a serious problem for developers to get things working fine cross-browser
without anti-patterns.

[0]
[https://github.com/facebook/react/issues/6436](https://github.com/facebook/react/issues/6436)

------
borplk
I was already thinking "but what about Typescript..." then saw it already
supports it :)

Well done react team and contributors.

------
mcphage
Why can't they automatically wrap every bit of JSX with a <Fragment> tag? That
way users would need to include an empty tag when they're returning multiple
elements, and they're not it'll be a fragment tag that just contains a single
element.

~~~
danabramov
Because you don't know where JSX ends and code begins. Don't forget that
fragments can include text nodes too.

return <div />

// am I a comment? Or text after div?

~~~
mcphage
Ah, hmm... good catch.

------
Klathmon
This is a bit off topic, but does anyone reading this happen to know the
status of async rendering in react?

There was chatter about it for version 16, and then nothing really else. I'm
curious about what they are testing or at least planning in this area.

Unfortunately i've found it really hard to search for anything related to
async rendering for react, as there is just so much other crap about react and
"async" it just gets lost.

~~~
danabramov
You can track it here. Still plenty of work to do but we are making progress.

[https://github.com/facebook/react/issues/8830](https://github.com/facebook/react/issues/8830)

[https://github.com/facebook/react/issues/11566](https://github.com/facebook/react/issues/11566)

~~~
Klathmon
Thank you! This is exactly what I was looking for and it seems all search
engines have failed me!

------
megous
No mention of prior work? This is part of web platform since forever. See
document.createDocumentFragment().

~~~
acdlite
We did mention some prior art in the section discussing the new syntax:

> Fragment syntax in JSX was inspired by prior art such as the XMLList() <></>
> constructor in E4X. Using a pair of empty tags is meant to represent the
> idea it won’t add an actual element to the DOM.

You're right that we could have referenced document.createDocumentFragment(),
too. Perhaps we'll add that to the documentation. Thanks for the suggestion!

~~~
megous
Thanks, it's a useful part of the DOM, perhaps somewhat overlooked.

------
Fifer82
I just can't help but sneer. Opinionated document.write() using "jsx".

Working with react has been the worst experience of my life. I had to call a
meeting and laid in down in October. If 2018 is React, I am leaving on Dec 31.

So soon I am going swiftly back into the arms of Angular and I can't wait.
Honestly, my eyes are blurring as I type this with pure happiness.

Enjoy the fragments guys, it will be good practice for picking up what little
is left of your happiness and transferable skill set in years to come.

~~~
sotojuan
Next time post this kind of stuff on your blog, not HN comments.

