Почему Fragments in React 16 лучше, чем контейнеры?
В React 16.2 добавлена улучшенная поддержка Fragments
. Более подробную информацию можно найти в блоге React здесь.
Мы все знакомы со следующим кодом:
render() {
return (
// Extraneous div element :(
<div>
Some text.
<h2>A heading</h2>
More text.
<h2>Another heading</h2>
Even more text.
</div>
);
}
Да, нам нужен контейнер div, но это не так уж важно.
В React 16.2 мы можем сделать это, чтобы избежать окружающего контейнера div:
render() {
return (
<Fragment>
Some text.
<h2>A heading</h2>
More text.
<h2>Another heading</h2>
Even more text.
</Fragment>
);
}
В любом случае нам все еще нужно, чтобы элемент контейнера окружал внутренние элементы.
Мой вопрос: зачем использовать Fragment
предпочтительнее? Помогает ли это в производительности? Если да, то почему? Хотелось бы немного прозреть.
Ответы
Ответ 1
- Это немного быстрее и требует меньше памяти (не нужно создавать дополнительный узел DOM). Это имеет реальную выгоду только на очень больших и/или глубоких деревьях, но производительность приложений часто страдает от смерти на тысячу сокращений. Это на один шаг меньше.
- Некоторые механизмы CSS, такие как Flexbox и CSS Grid, имеют особые отношения родитель-потомок, и добавление
div
в середине затрудняет сохранение желаемого макета при извлечении логических компонентов.
- Инспектор DOM менее загружен. :-)
Вы можете найти описания некоторых других вариантов использования в этой проблеме React: Добавить фрагмент API, чтобы разрешить возврат нескольких компонентов из рендера
Ответ 2
Добавление ко всем ответам выше дает еще одно преимущество: удобочитаемость кода, компонент Fragment
поддерживает синтаксическую сахарную форму, <>
. Таким образом, код в вашем вопросе может быть написан легче как:
render() {
return (
<>
Some text.
<h2>A heading</h2>
More text.
<h2>Another heading</h2>
Even more text.
</>
);
}
Согласно документам,
В React это происходит с помощью <React.Fragment/>
, как в примере из предыдущего раздела. (Non-React-фреймворки, использующие JSX, могут компилироваться во что-то другое.)
Без помех, верно?
Обратите внимание, что вам все еще нужно использовать синтаксис <Fragment>
если вам нужно предоставить key
к фрагменту.
Ответ 3
- Добавлены функции, недоступные ранее с помощью JSX
- Улучшенная семантическая разметка jsx. Элементы обертки используются в случае необходимости не потому, что они вынуждены.
- Меньшая общая разметка dom (увеличенная производительность рендеринга и меньшие издержки памяти)
Это так же просто, как когда вам не нужен элемент оболочки, вы не должны его использовать. Если учесть меньшее количество элементов, но я думаю, что самое большое преимущество в том, что они могут отображать элементы в jsx, которые ранее не были возможны, и добавляли лучшее семантическое значение для элементов оболочки, потому что теперь они являются необязательными.
Это было невозможно раньше:
<select>
{this.renderOptions()}
</select>
Взглянув на следующее в React 15, вы не можете определить, нужен ли элемент-оболочка или нет:
<span>
<h1>Hello</h1>
{this.getContent()}
</span>
Ответ 4
Согласно документам reatjs.org, наиболее важными потребностями <Fragments> <Fragments/>
вместо div являются недопущение нарушения семантики HTML. Когда мы используем div вместо <Fragments> <Fragments/>
мы нарушаем семантику HTML. узнать больше о семантике HTML. пожалуйста, нажмите, а также в некоторых случаях, если вы используете div вместо Fragments, это будет недействительным HTML, например, посмотрите на этот код.
class Columns extends React.Component {
render() {
return (
<div>
<td>Hello</td>
<td>World</td>
</div>
);
}
}
Result in table output of Columns Component
<table>
<tr>
<div>
<td>Hello</td>
<td>World</td>
</div>
</tr>
</table>
Фрагменты решают эту проблему.
Ответ 5
- Используя
<React.Fragment>...</React.Fragment>
, мы можем добавить родительский тег к нашим элементам JSX без добавления дополнительного узла в DOM.
- Вы можете заменить дополнительные теги div на React.Fragment
- писать React.Fragment каждый раз слишком долго для вас. React.Fragment имеет сокращенный синтаксис, который вы можете использовать. Это
<>...</>.