I'm a full-stack product engineer.
I work at Stream, helping companies make apps with scalable and personalized activity feeds.
I'm a big fan of building dumb fun web stuff and wrenching on rusty old cars.
this is more of a "hey, these exist!" kind of talk than an "in-depth tips and tricks" talk
If you'd like to revisit this later:
Slides: | ken.hoff.tech/slides/fragments |
Winds 2.0 is an RSS reader and podcast player that showcases activity feeds from Stream.
Check it out at https://getstream.io/winds/.
class App extends Component {
render() {
return (
<p>I would</p>
<p>really like</p>
<p>to render</p>
<p>an array</p>
);
}
}
womp womp:
Failed to compile.
./src/App.js
Syntax error: Adjacent JSX elements must be wrapped in an enclosing tag (6:8)
4 | return (<p>I would
5 | </p>
6 | <p>
| ^
7 | really like
8 | </p>
9 | <p>
class App extends Component {
render() {
return (
<div>
<p>I would</p>
<p>really like</p>
<p>to render</p>
<p>an array</p>
</div>
);
}
}
(or)
class App extends Component {
render() {
return [
<p>I would</p>,
<p>really like</p>,
<p>to render</p>,
<p>an array</p>
];
}
}
(notice the commas! because we're returning a JS object / array, it's okay.)
instead of
class App extends Component {
render() {
return [
<p>I would</p>,
<p>really like</p>,
<p>to render</p>,
<p>an array</p>
];
}
}
we use
class App extends Component {
render() {
return (
<React.Fragment>
<p>I would</p>
<p>really like</p>
<p>to render</p>
<p>an array</p>
</React.Fragment>
);
}
}
depending on your tooling (build pipeline, linters, beautifiers, etc), this might also work
class App extends Component {
render() {
return (
<>
<p>I would</p>
<p>really like</p>
<p>to render</p>
<p>an array</p>
</>
);
}
}
(see, the blog post says that this is supported in some tools, but create-react-app
doesn't support it yet, so use at your own risk)
React Fragments should be used when the styling / layout of your elements are dependent on their order / nesting
technically correct (but kind of contrived) examples:
table
, tr
, and td
)ul
, ol
, and li
)dt
, dd
, and dl
)whenever you need to get rid of a div
when you need to turn this rendered output:
<div class="app">
(...a bunch of other elements)
<div> (my react component)
<ComponentA></ComponentA>
<ComponentB></ComponentB>
<ComponentC></ComponentC>
</div>
(...a bunch more elements)
</div>
into this rendered output:
<div class="app">
(...a bunch of other elements)
<ComponentA></ComponentA>
<ComponentB></ComponentB>
<ComponentC></ComponentC>
(...a bunch more elements)
</div>
grid layout:
(brand / top-level nav) | content header |
| content |
.grid {
display: grid;
grid-template-areas:
'topnav header'
'subnav content';
grid-gap: 1em;
}
basically, we want this:
<div className="grid">
<TopNav />
<SubNav />
<ContentComponent />
</div>
to render something like this:
<div class="grid">
<div class="topnav" />
<div class="subnav" />
<div class="header" />
<div class="content" />
</div>
if our ContentComponent
renders an extra div:
class ContentComponent extends Component {
render() {
return (
<div>
<div className="header"/>
<div className="content"/>
</div>
);
}
}
it totally screws up our CSS grid.
<div class="grid">
<div class="topnav" />
<div class="subnav" />
<div>
<div class="header" />
<div class="content" />
</div>
</div>
<div className="grid">
<TopNav />
<SubNav />
<ContentComponent />
</div>
class ContentComponent extends Component {
render() {
return (
<React.Fragment>
<div className="header"/>
<div className="content"/>
</React.Fragment>
);
}
}
<div class="grid">
<div class="topnav" />
<div class="subnav" />
<div class="header" />
<div class="content" />
</div>
class ContentComponent extends Component {
render() {
return (
<React.Fragment>
<div className="header"/>
<div className="content"/>
</React.Fragment>
);
}
}
React.Fragment