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)

🌚 Life is too short to browse without dark mode