DEV Community

Cover image for Matt's Tidbits #96 - Cleaner Components with React Fragments
Matthew Groves
Matthew Groves

Posted on • Originally published at matthew-b-groves.Medium

Matt's Tidbits #96 - Cleaner Components with React Fragments

Last time, I wrote about defining constants in TypeScript. This week, I want to share what I learned about React Fragments!

To many of my readers who are Android developers, you already know all about Fragments from the standpoint of building Android UI. However, in the React/React Native world, Fragments serve an entirely different purpose.

First, an example — say you want to define a method (or component) that returns some elements, for example:

const Stack = createStackNavigator()
const SomeComponent = () => {
  return (
    <Stack.Navigator>
      getScreens()
    </Stack.Navigator>
  );
};
Enter fullscreen mode Exit fullscreen mode

A likely first implementation of getScreens() would return an array (at least, this is how I did this at first):

const getScreens = () => {
  return [
    <Stack.Screen name="Screen1" component={Screen1Component} />,
    <Stack.Screen name="Screen2" component={Screen2Component} />,
    ...
  ];
};
Enter fullscreen mode Exit fullscreen mode

Unfortunately, this approach will yield a compiler warning:

Warning: Each child in a list should have a unique "key" prop
Enter fullscreen mode Exit fullscreen mode

The reason for this is that React dictates that every element in a list must have a uniquely identifiable “key” property — largely to assist in comparing two versions of the same list — were new elements added, were some elements removed, or did existing elements change position in the list? This is a great feature, but in the case of our list of Screens, it’s somewhat redundant to have to define a “key” property on each item. We already have a unique “key” (the name field), and besides, we’re not expecting this list to change over time.

Thankfully, React provides a cleaner solution to this very problem — Fragments!

Here’s what getScreens() would look like if we use a Fragment instead:

const getScreens = () => {
  return (
    <React.Fragment>
      <Stack.Screen name="Screen1" component={Screen1Component} />
      <Stack.Screen name="Screen2" component={Screen2Component} />
    </React.Fragment>
  );
};
Enter fullscreen mode Exit fullscreen mode

Voilà! This works just as well, we don’t have to add commas to the end of each line, and, most importantly, we don’t need to define a “key” property on each item.

There’s one more neat shorthand you can use, and that is to replace <React.Fragment> with the short syntax <> to further clean this up and make it clear that the Fragment is really just a wrapper.

An alternative approach would be to wrap elements within a React <div> or React Native <View> element, however, this has a few drawbacks:

  • You’re actually adding an additional item to the view hierarchy — Fragments disappear during the rendering process.
  • Some scenarios, like the React Navigation example above, will not allow for any element other than a <Stack.Screen> to be embedded directly within a <Stack.Navigator> — leaving Fragments as the only viable option.

I hope you learned something useful about Fragments that will help improve your React code! Do you use Fragments in other/unique ways? I’d love to hear about it in the comments!

Interested in working with me in the awesome Digital Products team here at Accenture? We’re hiring!

Top comments (0)