loading...

React Fragments

sarah_chima profile image Sarah Chima Updated on ・3 min read

Part of the JSX syntax is that adjacent JSX elements are wrapped in an enclosing tag. That is, a JSX expression must have only one outermost element. Adhering to this rule might mean adding an extra DOM node even when it is not necessary. Thanks to React Fragments, we do not need to do this.

Let me explain this problem further using an example.

The Problem

Let us assume that we have a form and we want to the input field to be custom components with labels.

class Form extends Component {
    render() {
        return (
            <form>
                <InputField name="Name"/>
                <button>Submit</button>
            </form>
        )
    }
}

Then for the InputField component, we have the following:

class InputField extends Component {
    render() {
        return (
            <div>
                <label>{this.props.name}</label>
                <input placeholder={this.props.name} />
            </div>
        )
    }
}

Notice how we had to wrap the label and the input field in a div. We did this to adhere to the JSX syntax. This is the output of the above in the DOM.

<form>
    <div>
        <label>Name</label>
        <input placeholder="Name">
    </div>
    <button>Submit</button>
</form>

Here are some issues related to this addition:

  1. Introducing an extra and unnecessary node into the DOM leads to more DOM clutter. If we do this for a lot of other components, we will have so many extra nodes in the DOM. This might have very little impact on small applications. But in very large applications where performance is important, adding extra DOM nodes lead to increased memory usage.

  2. It makes the use of CSS mechanisms like FlexBox and CSS Grid more complicated. These mechanisms depend on the relationship that exists between parent and child elements. So breaking such relationship by introducing an extra div makes styling more complicated.

The good news is that React fragments solve this problem. Let us see how.

Meet Fragments Officially

Fragments let you group a list of children without adding extra nodes to the DOM. We use it exactly the same way we use the div to wrap the elements in the InputField element. Let's do this.

class InputField extends Component {
    render() {
        return (
            <React.Fragment>
                <label>{this.props.name}</label>
                <input placeholder={this.props.name} />
            </React.Fragment>
        )
    }
}

This will be transpiled to


<form>
    <label>Name</label>
    <input placeholder="Name">
    <button>Submit</button>
</form>

Yay!! No extra div added.

We can use it without referencing the React object by importing it from react using object destructuring.

import React, { Component, Fragment } from 'react'

class InputField extends Component {
    render() {
        return (
            <Fragment>
                <label>{this.props.name}</label>
                <input placeholder={this.props.name} />
            </Fragment>
        )
    }
}

Attributes of the Fragment

Or rather, the attribute of the fragments. Fragments support only one attribute - the key attribute. This is especially useful for lists where keys are required for each list item. An example is the description list below:


class TodoList extend Component {
    render() {
        return (
            <dl>
            ${this.props.todos.map(todo =>
                <React.Fragment key={todo.id}>
                    <dt>{todo.name}</dt>
                    <dd>{todo.description}</dd>
                </React.Fragment>
            )
            </dl>
        )
    }
}

Newer Shorter Syntax

A newer shorter syntax for writing fragments is declaring Fragments. It is by using <> and </> instead of Fragment. Yeah I know, they look like empty tags.

class InputField extends Component {
    render() {
        return (
            <>
                <label>{this.props.name}</label>
                <input placeholder={this.props.name} />
            </>
        )
    }
}

A drawback of this syntax is that it does not support keys or attributes. It is also not supported by many tools, so you might want to write out the Fragments explicitly.

Conclusion

React Fragments are cool and you should use them.

Thank you for reading.😊

Posted on Oct 20 '17 by:

sarah_chima profile

Sarah Chima

@sarah_chima

A Frontend web developer interested in making the web accessible for everyone.

Discussion

markdown guide
 

Hi Sarah,
Great post. I never thought of doing an Input component before, so that was also a great addition skill beyond the Fragment explanation too.
Also I think if you look you see two things, one I believe is an error and the second is what I believe to be a best practice for usability.

  1. Your second last example uses props not this, yet it's a Class declaration. What's tongue-in-cheek cute about the oversight is that you caught it on your next example and used this.

  2. I believe Labels should enclose the input tag for usability reasons. Which if I'm right then it means that extra

    isn't necessary.

    Regardless even if I'm right about any of those this was as I've said an awesome and easy to follow Fragment article. I've read a few as I try to process and learn to develop better with React and yours is good.

    Have a great week!

 

Thanks Roger, I'm glad you like the post. Thanks also for pointing out the error. I used the input field solely for an explanation. Should use a better example next time.

 

Oh my no it was great. I'm just in the early stages of learning React so for me I loved your Input component and I was serious about replicating it in some form in my own work. I recognize you it's just an 'example', but does that also mean making each input into a component as you've done isn't a good idea?

Btw I tried to use your lesson yesterday and couldn't quite get it to work. Darn! I was so excited to try Fragments finally.

Again thank you for your article. Don't feel bad about your examples, they were very helpful, so in that context they were the perfect choices :)

 

Great post. Previously I had only seen the React.Fragment or <> </> methods for using fragments. That’s cool to see the destructuring method to use instead. I like that as it semantically helps to know what the element is doing and helping build tools is great too.

 

That's not destructuring, it is a named import.

Differences: youtube.com/watch?v=4keUSxNw-KE

 

Thanks Dave. I'm glad you find the post useful.

 

I just used the destructuring approach in a Gatsby project of mine. When I first implemented it the code didn't compile, so I came back to this post and found my mistake. I had messed up the import statement. Thanks again!

We all make mistakes as devs. I'm glad the post helped you to fix it.

Oh yes. I’m more than happy to make mistakes and learn from them.

 

I wonder if there is a performance difference between the two ways of using it. If there was, probably not significant... But if you use React.Fragment in a component where the logic is to conditionally render some jsx or null, would it act like a dynamic import?

 

Thanks Sarah.

I liked how the Fragment can be used and what problem it solves 😄

 

I'm glad you like it. Thank you.

 

Hi sarah,
Great post!,it's really helpful to understand in detail about fragment.Now i got the perfect definition about fragment,expecting more post like this

Thank you

 

Thank you for reading it.