React component closing tag

21,486

Solution 1

In React's JSX, you only need to write <MyComponent></MyComponent> when the component has child components, like this:

<MyComponent>
    <Child />
    <Child />
    <Child />
</MyComponent>

If there is nothing between <MyComponent> and </MyComponent>, then you can write it either <MyComponent/> or <MyComponent></MyComponent> (but <MyComponent/> is generally preferred). Details in Introducing JSX.

Just as a side note, you'd access those children in your component via the special props.children property. More in JSX in Depth: Children in JSX.

Note that this is very much not like HTML or XHTML. It's its own (similar) thing with different rules. For instance, in HTML, <div/> is exactly the same thing as <div>: A start tag, for which you must eventually have an end tag. Not so JSX (or XHTML). The rules for HTML are that void elements (elements that never have markup content, such as br or img) can be written with or without / before > and they never get an ending tag, but non-void elements (like div) must always have an ending tag (</div>), they cannot be self-closing. In JSX (and XHTML), they can be.

Solution 2

The purpose of self-closing tags is simply the fact that it is more compact. This is especially useful when said component doesn't have any children that you typically wrap around a parent.

So usually for leaf components (i.e compoents that do not have any children), you use the self-closing syntax. Like: <Component />. And even if it has props, you can do: <Component foo="bar" />.

However, remember that children is a prop, so you could technically do:

<Component children={<span>foo</span>} />

but I find it less readable and advise against it (read disclaimer below).


To summarize, these are equivalent:

  • <Component /> = <Component></Component>
  • <Component foo="bar" /> = <Component foo="bar"></Component>
  • <Component children={<span>foo</span>}></Component> =

    <Component><span>foo</span></Component>

You can use whichever approach you prefer. Though praxis is to use the short-hand version when there are no children.


Disclaimer: While defining childen prop by its object key value will technically work, doing so is strongly discouraged as it disrupts the API as it is meant to be used. Use this version only if confident in what you are doing.

Share:
21,486
Chimera.Zen
Author by

Chimera.Zen

My first house was in the city of Geo. Oh, how I loved that repository of poorly coded, midi-heavy pages with their seizure-inducing blinks declaring my love of all things a 90's teen coder could love...korn, slipknot and starcraft:broodwar :D

Updated on February 27, 2020

Comments

  • Chimera.Zen
    Chimera.Zen about 4 years

    I'm new to React and I'm trying to figure out the purpose/use of <MyComponent></MyComponent> vs <MyComponent />. I can't seem to find information on anything except self-closing tags.

    I've created a basic tab scroller as a JSFiddle using the self-closing <MyComponent /> and subsequent props, and I'm wondering if there's a better way to write in React than what I've done.

    class TabScroller extends React.Component {
    
      render() {
        return (
          <div className="tabScroller">
            <div className="NavList">
              <TabNav handleClick={this.handleNavClick} />
              <TabList 
                tabs={this.state.tabs} 
                activeTab={this.state.activeTab}
                scrollPosition={this.state.scrollPosition} 
                handleClick={this.handleTabClick}
              />
            </div>
            <TabContent content={this.state.tabs[this.state.activeTab].content} />
          </div>
        );
      }
    }
    
    // ========================================
    
    ReactDOM.render(
      <TabScroller />,
      document.getElementById('root')
    );
    
  • T.J. Crowder
    T.J. Crowder about 6 years
    Interestingly, the children={...} form seems to be undocumented; it's not mentioned in Introducing JSX > Specifying Children with JSX or in JSX In Depth > Children In JSX. The docs also refers to props.children as a "special" property. Of course, we know the JSX is transpiled to a React.createElement call with a children option property, but... While it may work at present, I think I'd either avoid mentioning it, or use a stronger disclaimer.
  • Chimera.Zen
    Chimera.Zen about 6 years
    Thanks to your information, I found React Composition vs Inheritance which also adds that the multiple <Child />'s are passed to <MyComponent></MyComponent> as props.children
  • Chimera.Zen
    Chimera.Zen about 6 years
    THIS! The JSX In Depth link gave me everything I've been wanting to know! Although you've given me a new question @t-j-crowder which is, why do you think it's a bad idea to use props.children? is there another means of accessing or passing the child components?
  • Chris
    Chris about 6 years
    @T.J.Crowder, indeed. Facebook has deliberately chosen not to keep that undocumented because by doing so it could encourage people to use that format which would cause problems with the API later on, should they ever want to change that part. It's kind of "meant" to be a hidden prop. So yes, you make a valid point. I don't want to remove it entirely because I think it is somewhat valuable to the comparisons, but I'll add the disclaimer you proposed. Thanks.
  • Chris
    Chris about 6 years
    @Chimera.Zen T.J.Crowder means one should not pass the children prop as <Component children={...} />, but only as <Component>{...}</Component>. However, accessing children can and should be done with props.children. Don't mix up passing and accessing.
  • T.J. Crowder
    T.J. Crowder about 6 years
    @Chimera.Zen: See Chris' comment above, I'm just talking about children={<span>foo</span>}. To use children, you use props.children, which is just fine (indeed, you have no other choice).
  • T.J. Crowder
    T.J. Crowder about 6 years
    @Chris: I think you mean they've chosen to keep it undocumented, rather than the double-negative. :-)
  • Chris
    Chris about 6 years
    @T.J.Crowder, by the way, not sure what you meant by "with a children option property", but using children={...} will actually transpile to React.createElement(Component, {children: ...}, null), rather than React.createElement(Component, null, ...). (where ... a component)
  • Chris
    Chris about 6 years
    @T.J.Crowder oops, yes :P
  • T.J. Crowder
    T.J. Crowder about 6 years
    @Chris: Right, that's a children property on the option object passed as the second argument to React.createElement. Except I see it's not an option object, it's a props object. :-D Oops.
  • Chris
    Chris about 6 years
    @T.J.Crowder, now try React.createElement(Component, {children: X}, Y)... xD
  • T.J. Crowder
    T.J. Crowder about 6 years
    @Chris: Oh, I realize.