<Fragment> (<>...</>)

<Fragment>, часто используемый с помощью синтаксиса <>...</>, позволяет группировать элементы без оборачивания в дополнительный тег.

<>
<OneChild />
<AnotherChild />
</>

Справочник

<Fragment>

Оберните элементы в <Fragment>, чтобы сгруппировать их вместе в тех случаях, когда вам необходим единственный элемент. Группировка элементов с помощью Fragment не влияет на конечный DOM; он остается таким же, как если бы элементы не были сгруппированы. Пустой JSX-тег <></> в большинстве случаев является сокращением для <Fragment></Fragment>.

Пропсы

  • необязательный key: Фрагменты объявленные с помощью явного синтаксиса <Fragment> могут иметь ключи.

Предостережения

  • Если вам необходимо передать key фрагменту, вы не можете использовать краткий синтаксис <>...</>. Вы должны явно импортировать Fragment из 'react' и рендерить <Fragment key={yourKey}>...</Fragment>.

  • React не сбрасывает состояние когда вы переключаетесь между рендерингом <><Child /></> к [<Child />] или обратно, или между <><Child /></> и <Child />. Однако, это работает только на одном уровне вложенности. Например, когда вы переключаетесь от <><><Child /></></> к <Child />, то состояние будет сброшено. Точную семантику можно посмотреть здесь.


Применение

Возвращение нескольких элементов

Используйте Fragment или аналогичный синтаксис <>...</>, чтобы сгруппировать несколько элементов. Вы можете использовать его для размещения нескольких элементов в любом месте, где может находиться один элемент. Например, компонент может возвращать только один элемент, но используя Fragment, вы можете сгруппировать несколько элементов вместе и затем вернуть их как группу:

function Post() {
return (
<>
<PostTitle />
<PostBody />
</>
);
}

Фрагменты полезны тем, что группировка элементов с их помощью не влияет на отображение элементов на странице или стили, в отличие от случая, когда вы оборачиваете элементы в другой контейнер, например, в DOM-элемент. Если вы проверите этот пример с помощью инструментов браузера, то увидите, что все DOM-узлы <h1> и <p> отображаются как соседи без оберток вокруг них:

export default function Blog() {
  return (
    <>
      <Post title="Обновление" body="Давненько я не писал..." />
      <Post title="Мой новый блог" body="Я начинаю новый блог!" />
    </>
  )
}

function Post({ title, body }) {
  return (
    <>
      <PostTitle title={title} />
      <PostBody body={body} />
    </>
  );
}

function PostTitle({ title }) {
  return <h1>{title}</h1>
}

function PostBody({ body }) {
  return (
    <article>
      <p>{body}</p>
    </article>
  );
}

Deep Dive

Как написать фрагмент без использования особого синтаксиса?

Приведенный выше пример эквивалентен импорту Fragment из React:

import { Fragment } from 'react';

function Post() {
return (
<Fragment>
<PostTitle />
<PostBody />
</Fragment>
);
}

В большинстве случаев это не нужно, за исключением ситуаций, когда необходимо передать фрагменту key.


Присвоение переменной нескольких элементов

Как и любой другой элемент, вы можете присваивать элементы Fragment переменным, передавать их в качестве пропсов и так далее:

function CloseDialog() {
const buttons = (
<>
<OKButton />
<CancelButton />
</>
);
return (
<AlertDialog buttons={buttons}>
Вы уверены, что хотите покинуть эту страницу?
</AlertDialog>
);
}

Группировка элементов с текстом

Вы можете использовать Fragment чтобы сгруппировать текст вместе с компонентами:

function DateRangePicker({ start, end }) {
return (
<>
С
<DatePicker date={start} />
до
<DatePicker date={end} />
</>
);
}

Рендеринг списка фрагментов

Рассмотрим ситуацию, когда вам нужно явно написать Fragment, вместо использования синтаксиса <></>. Это может понадобиться, когда вы рендерите несколько элементов в цикле и каждому элементу нужно присвоить key. Если элементы в цикле являются фрагментами, то вам необходимо использовать стандартный синтаксис JSX-элементов, чтобы предоставить атрибут key:

function Blog() {
return posts.map(post =>
<Fragment key={post.id}>
<PostTitle title={post.title} />
<PostBody body={post.body} />
</Fragment>
);
}

Вы можете проверить DOM, чтобы убедиться, что вокруг дочерних элементов фрагмента нет оберток:

import { Fragment } from 'react';

const posts = [
  { id: 1, title: 'Обновление', body: "Давненько я не писал..." },
  { id: 2, title: 'Мой новый блог', body: 'Я начинаю новый блог!' }
];

export default function Blog() {
  return posts.map(post =>
    <Fragment key={post.id}>
      <PostTitle title={post.title} />
      <PostBody body={post.body} />
    </Fragment>
  );
}

function PostTitle({ title }) {
  return <h1>{title}</h1>
}

function PostBody({ body }) {
  return (
    <article>
      <p>{body}</p>
    </article>
  );
}