React组件的闭合标签

26

我是React的新手,正在试图弄清楚<MyComponent></MyComponent>与<MyComponent />的用途/用法。除了自闭合标签之外,我似乎找不到其他信息。

我使用自闭合的<MyComponent />和随后的props创建了一个基本的选项卡滚动条,您可以在JSFiddle上查看,并且我想知道是否有更好的编写React的方法。

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')
);
2个回答

49
在React的JSX中,只有当组件具有子组件时,才需要编写 <MyComponent></MyComponent>,如下所示:
<MyComponent>
    <Child />
    <Child />
    <Child />
</MyComponent>

如果在 <MyComponent></MyComponent> 之间没有任何内容,那么你可以将它写成 <MyComponent/><MyComponent></MyComponent>(但通常情况下偏好使用 <MyComponent/>)。详情请参见Introducing JSX

需要注意的是,这与 HTML 或 XHTML 非常不同。它是一种独立的(类似)语言,具有不同的规则。例如,在 HTML 中,<div/><div> 是完全相同的:都是开始标签,必须最终有结束标签。但在 JSX(或XHTML)中,则不是这样。HTML 的规则是,空元素(从不包含任何内容的元素,如 brimg)可以在 / 之前或之后写上 >,它们从不获得结束标记,但非空元素(如 div)必须始终有一个结束标记(</div>),它们不能是自闭合的。而在JSX(或XHTML)中,则可以是这样。

另外需要注意的是,你可以通过 props.children 特殊属性来访问组件中的子元素。详情请参见JSX in Depth: Children in JSX


3
感谢您的信息,我找到了React 组合 vs 继承 的相关内容,并且它还提到多个 <Child /> 作为 props.children 传递给了 <MyComponent></MyComponent> - Chimera.Zen

14
自闭合标签的目的是为了更加紧凑。当一个组件没有子元素需要包含时,这就变得尤为有用。
通常情况下,对于“叶子组件”(即没有任何子元素的组件),您可以使用自闭合语法,例如:<Component />。即使它具有属性,也可以这样写:<Component foo="bar" />
但要记住,children 是一个属性,因此您可以通过以下方式进行操作: <Component children={<span>foo</span>} /> 但我认为这种写法不太易读,建议避免使用(请参见下面的免责声明)。
总之,以下写法等效:
  • <Component /> = <Component></Component>
  • <Component foo="bar" /> = <Component foo="bar"></Component>
  • <Component children={<span>foo</span>}></Component> = <Component><span>foo</span></Component>
您可以根据需要选择任何一种方法。在没有子元素时,缩略版本通常是首选做法。
免责声明:通过对象键值定义children属性虽然在技术上可行,但这样做不被推荐,因为它会扰乱API的正常使用。仅在您对自己的操作非常自信时才使用该版本。

1
有趣的是,children={...} 的形式似乎没有记录; 在Introducing JSX > Specifying Children with JSXJSX In Depth > Children In JSX中都没有提到。文档还将props.children称为“特殊”的属性。当然,我们知道JSX被转译为带有children选项属性的React.createElement调用,但是......虽然它现在可能有效,但我认为我要么避免提及它,要么使用更强的免责声明。 - T.J. Crowder
2
@Chimera.Zen T.J.Crowder 的意思是不应该将 children 属性作为 <Component children={...} /> 进行传递,而应该只使用 <Component>{...}</Component>。然而,访问 children 可以并且应该使用 props.children。不要混淆传递和访问。 - Chris
1
@Chimera.Zen:请看上面Chris的评论,我只是在谈论children={<span>foo</span>}。要使用children,您需要使用props.children,这很好(事实上,您别无选择)。 - T.J. Crowder
1
@Chris:我想你的意思是他们选择不记录它,而不是双重否定。 :-) - T.J. Crowder
1
@Chris:哦,我明白了。 - T.J. Crowder
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接