どうも、ノマドクリエイターのショウヘイ(@shohei_creator)です。
ブログアシスタントのふーちゃんです。
React では、コンポーネントの retrun 文として定義される返り値は、必ず 1 つの要素( DOM ノード)だけを設定する規則になっています。複数の要素を並べることは禁止です。
// 返り値が1つのdiv要素なので、OK
export const Component: React.VFC = () => {
return (
<div>
<p>段落1</p>
<p>段落2</p>
<p>段落3</p>
</div>
);
};
// 返り値が3つのp要素なので、NG
export const Component: React.VFC = () => {
return (
<p>段落1</p>
<p>段落2</p>
<p>段落3</p>
);
};
そこで、 React には、 Fragment (フラグメント)という特殊なタグが用意されています。フラグメントは、その内部に子要素を持つことができて、かつビルド時には消える特徴を持っています。
この記事では、 React の Fragment の使い方について説明します。
React の Fragment の基本構文と使い方
React の Fragment には、通常版とショートハンド版の 2 種類があります。
React の Fragment の通常版を使う時は、 react ライブラリから Fragment を import しておく必要があります。コンポーネントの返り値の要素として、 <Fragment> タグを設置してください。
import React, { Fragment } from "react";
export const Component: React.VFC = () => {
return (
<Fragment>
<p>段落1</p>
<p>段落2</p>
<p>段落3</p>
</Fragment>
);
};
React の Fragment のショートハンド版を使う時は、 react ライブラリから Fragment を import する必要はありません。コンポーネントの返り値の要素として、中身のない <> タグを設置してください。
react ライブラリから import する手間も無いので、自分はショートハンド版の Fragment を使うようにしています。
import React from "react";
export const Component: React.VFC = () => {
return (
<>
<p>段落1</p>
<p>段落2</p>
<p>段落3</p>
</>
);
};
React の Fragment を使った状態でビルドすると、ページには Fragment タグが反映されていないことが確認できます。
React の Fragment に key 属性を設定する方法
React の Fragment には、 key 属性だけ設定できます。それ以外の属性( className や style など)は設定できないので、注意してください。
map メソッドと Fragment を併用したい場合には、 Fragment に key 属性をつけておいた方がいいです。
また、ショートハンド版は使えないので、注意してください。
import React, { Fragment } from "react";
type Language = {
ttl: string;
desc: string;
};
export const Component: React.VFC = () => {
const languages: Language[] = [
{
ttl: "HTML",
desc: "ハイパーテキストをマークアップ形式で記述できる"
},
{
ttl: "CSS",
desc: "HTMLやXMLの要素を修飾できる"
},
{
ttl: "JavaScript",
desc: "Webページの要素をDOMとして参照・操作できる"
}
];
return (
<dl>
{languages.map((language) => (
<Fragment key={language.ttl}>
<dt>{language.ttl}</dt>
<dd>{language.desc}</dd>
</Fragment>
))}
</dl>
);
};
React では Fragment と div のどちらを使うべきか
特別な意味を持たない汎用的な HTML タグとして、 div タグが挙げられます。 React のコンポーネントの return 文に使う要素としては、 Fragment と同様の役割を担えそうです。
「 React の Fragment は、 div タグよりもベンチマーク結果が悪い」という趣旨の記事もありますが、よほど大規模な開発でないかぎりは、 Fragment を使えばいいと個人的に感じています。
もともと、 React に Fragment が導入された理由は、 DOM に余計なノードを追加せずに子要素をまとめられるようにするためです。ブラウザのパフォーマンス向上は意図されていません。
フラグメント (fragment) を使うことで、 DOM に余分なノードを追加することなく子要素をまとめることができるようになります。
フラグメント - React
このあたりは、実装者の好みの問題になりそうです。
本当に大規模な開発でないかぎりは、好きな方を使えばいいと思いますね。