React+JSXでは1つの要素しか返却してはいけないのでFragmentを使う

React+JSXでは1つの要素しか返却してはいけないのでFragmentを使う
目次

今日は React の小ネタです。

ReactのJSX

React ではエレメントをコンポーネント化する仕組みとして JSXを使います。

Function ComponentやReact Componentを書く場合には以下のようにreturnの中に要素を書きます。

1const SomeComponent: React.FC = () => {
2  // ここに要素を書く
3  return (
4    <div>
5      hogehoge
6    </div>
7  )
8}
9export default SomeComponent;

Returnするエレメントが複数ある場合にはエラーになる

ここで、以下のような要素を2つ返却するコンポーネントを書いてみます。

 1const SomeComponent: React.FC = () => {
 2  return (
 3    <div>
 4      hogehoge
 5    </div>
 6    <div>
 7      fugafuga
 8    </div>
 9  )
10}
11export default SomeComponent;

すると以下のようなエラーに出くわします。

Parsing error: JSX expressions must have one parent element

JSXではReturnする要素が複数あると(今回はdivタグ2つ)エラーとなってしまいます。

単純な解決策として、本来返却したい複数のタグを更にdivタグで囲うなどして1つにまとめる方法が思いつくでしょう。 しかしこの方法は不要なタグを書くことになるのでスマートな解決策とは言えません。

 1const SomeComponent: React.FC = () => {
 2  return (
 3    <div>
 4      <div>
 5        hogehoge
 6      </div>
 7      <div>
 8        fugafuga
 9      </div>
10    </div>
11  )
12}
13export default SomeComponent;

React.Fragmentでグルーピングする

これを解決するために、 React.Fragment を使います。

 1const SomeComponent: React.FC = () => {
 2  return (
 3    <React.Fragment>
 4      <div>
 5        hogehoge
 6      </div>
 7      <div>
 8        fugafuga
 9      </div>
10    </React.Fragment>
11  )
12}
13export default SomeComponent;

React.Fragment では複数の要素をグルーピングすることができ、React.Fragment 自体がHTMLタグとして出力されることはありません。

なお React.Fragment にはシンタックスシュガーが存在します。実際には以下の方をよく利用します。

 1const SomeComponent: React.FC = () => {
 2  return (
 3    <>
 4      <div>
 5        hogehoge
 6      </div>
 7      <div>
 8        fugafuga
 9      </div>
10    </>
11  )
12}
13export default SomeComponent;

React.Fragmentを使う上での留意点

複数の要素をまとめてコンポーネントを返却できる便利な React.Fragment ですが、 UIフレームワークが提供するコンポーネントと組み合わせて動作するか は確認が必要です。

以前、 @material-ui/lab4.0.0-alpha.28SpeedDialActionReact.Fragment でラップして返却した場合に動作していないことを確認しています。 まぁ、この場合はLabなライブラリなので動かなくても仕方が無いのですけど。

参考にさせていただいたサイト

関連記事

soudegesu avatar
soudegesu について
Software Engineer
comments powered by Disqus