Featured image of post React Fragment

React Fragment

Reactにおいて、JSXコンポーネントは1つのタグで囲む必要がある。

TypeScriptであれば、以下のコンポーネントは記述した時点で JSX expressions must have one parent element. のエラーとなる。

1
2
3
4
5
6
export function SampleForm(props: Props) {
  return (
    <label {props.label}>
    <input {...props} />
  )
}

このような時に div で囲んでしまえば解決するが、不要なDOMがレンダリングされてしまうのが気になる。

React都合で、マークアップ上不要なDOMだ。

Fragmentを使うと、不要なDOMをレンダリングすることなく、Reactのルールに従うことができる

1
2
3
4
5
6
7
8
export function SampleForm(props: Props) {
  return (
    <>
      <label>{props.label}</label>
      <input {...props} />
    </>
  );
}

developer tool等でDOM構造を見てみると、SampleForm のlabelとinputは何にも囲まれてないことがわかる。

mapなどでリストをレンダリングする際は一意な key が必要になるため、明示的に Framgment の記述が必要。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import { Fragment } from 'react';

const forms = [
  { id: 1, label: 'Name', default: "Bob" },
  { id: 2, label: 'Email', default: '[email protected]' }
];

function SampleForm() {
  return forms.map(form =>
    <Fragment key={form.id}>
      <label>{form.label}</label>
      <input type='text' defaultValue={form.default} />
    </Fragment>
  );
}

(<>…</>) – React