React Fragments
You may have noticed that all of our React components return JSX with one top-level HTML element. When we introduced the Search component a while ago, we had to add a <div>
tag (read: container element), because otherwise the label and input elements couldn't be returned side-by-side without a wrapping top-level element:
src/App.jsx
jsx
const Search = ({ search, onSearch }) => (
<div>
<label htmlFor="search">Search: </label>
<input
id="search"
type="text"
value={search}
onChange={onSearch}
/>
</div>
);
However, there are ways to render multiple top-level elements side-by-side. A rarely used approach returns all sibling elements as an array. Since this resembles a list of elements, we would have to give each list item a mandatory key
attribute:
src/App.jsx
jsx
const Search = ({ search, onSearch }) => [
<label key="1" htmlFor="search">
Search:{' '}
</label>,
<input
key="2"
id="search"
type="text"
value={search}
onChange={onSearch}
/>,
];
Fortunately there exists another way of returning siblings elements side-by-side without a top-level element, because the last approach with the array doesn't turn out very readable and becomes verbose with the additional key attribute. Another solution is to use a React fragment:
src/App.jsx
jsx
const Search = ({ search, onSearch }) => (
<React.Fragment>
<label htmlFor="search">Search: </label>
<input
id="search"
type="text"
value={search}
onChange={onSearch}
/>
</React.Fragment>
);
A fragment wraps sibling elements into a single top-level element without adding them to the rendered output. See for yourself by inspecting the elements in your browser's development tools after using a fragment in your React component. A more popular alternative these days is using fragments in their shorthand version:
src/App.jsx
jsx
const Search = ({ search, onSearch }) => (
<>
<label htmlFor="search">Search: </label>
<input
id="search"
type="text"
value={search}
onChange={onSearch}
/>
</>
);
Both elements in the Search component - input field and label - should be still visible in your browser now. After all, whenever you don't want to introduce an intermediary element that's only there to satisfy React, you can use fragments as helper "elements".
Exercises:
- Compare your source code against the author's source code.
- Recap all the source code changes from this section.
- Optional: If you are using TypeScript, check out the author's source code here.
- Optional: Leave feedback for this section.