React Fragment

在 React 16 以前,你需要把 children elements 包在一個 container element 下面,例如:

render() {
  return (
    // 你需要在外面包一層 container 像是 <div>
    <div>
      Some text.
      <h2>A heading</h2>
      More text.
      <h2>Another heading</h2>
      Even more text.
    </div>
  );
}

但這限制也帶來缺點和不便:

  1. 你會在 DOM 中多了一個不必要的節點

  2. 有時候反而造成不合法的 HTML 結構

    像是這例子:

    class Table extends React.Component {
      render() {
        return (
          <table>
            <tr>
              <Columns />
            </tr>
          </table>
        );
      }
    }
    

    <Columns /> 元件理論上需要返回 <td> 元素,但因為還需要包一層父元素:

    class Columns extends React.Component {
      render() {
        return (
          <div>
            <td>Hello</td>
            <td>World</td>
          </div>
        );
      }
    }
    

    所以最後 <table> 中多出個 <div>,造成無效的 HTML

    <table>
      <tr>
        <div>
          <td>Hello</td>
          <td>World</td>
        </div>
      </tr>
    </table>
    

React 16.2 開始提供了 Fragment (片段) 功能,Fragment 讓你可以直接返回一組元素,而不需要增加多餘的 DOM 節點。

Fragment 的語法是使用 <React.Fragment>

class Columns extends React.Component {
  render() {
    return (
      <React.Fragment>
        <td>Hello</td>
        <td>World</td>
      </React.Fragment>
    );
  }
}

最後得到的新結果:

<table>
  <tr>
    <td>Hello</td>
    <td>World</td>
  </tr>
</table>

可以看到沒有多餘的 DOM 節點囉!

Fragment 另外提供了一個更簡潔 (short syntax) 的語法 <></>,它其實只是 <React.Fragment> 的語法糖:

class Columns extends React.Component {
  render() {
    return (
      <>
        <td>Hello</td>
        <td>World</td>
      </>
    );
  }
}

注意,不是所有的工具都已經支援 <></> 這語法。