<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> ); }