Какие атрибуты может принимать React Fragment?

👨‍💻 Frontend Developer 🟠 Может встретиться 🎚️ Легкий
#React

Краткий ответ

React Fragment может принимать только один атрибут — key:

  1. key — единственный допустимый атрибут 🔑
  2. <React.Fragment> — полный синтаксис с атрибутами 📝
  3. <>…</> — короткий синтаксис без атрибутов ⚡
  4. Группировка — объединение элементов без DOM-узла 📦
  5. Списки — key нужен при рендере списков 📋
// С атрибутом key
<React.Fragment key={item.id}>
  <td>{item.name}</td>
  <td>{item.value}</td>
</React.Fragment>
 
// Короткий синтаксис (без атрибутов)
<>
  <h1>Title</h1>
  <p>Content</p>
</>

Полный ответ

React Fragment — это специальный компонент для группировки элементов без создания дополнительного DOM-узла! Он принимает только один атрибут — key. 🎯

1. Единственный атрибут — key

Fragment может принимать только атрибут key:

// ✅ Правильно - только key
<React.Fragment key="unique-key">
  <h1>Header</h1>
  <p>Paragraph</p>
</React.Fragment>
 
// ❌ Неправильно - другие атрибуты не поддерживаются
<React.Fragment className="container" id="wrapper">
  <div>Content</div>
</React.Fragment>

2. Синтаксис Fragment

Полный синтаксис с атрибутами

import React from 'react';
 
function ComponentWithKey() {
  const items = [
    { id: 1, name: 'Item 1', value: 'Value 1' },
    { id: 2, name: 'Item 2', value: 'Value 2' }
  ];
 
  return (
    <table>
      <tbody>
        {items.map(item => (
          <React.Fragment key={item.id}>
            <tr>
              <td>{item.name}</td>
              <td>{item.value}</td>
            </tr>
            <tr>
              <td colSpan="2">Description for {item.name}</td>
            </tr>
          </React.Fragment>
        ))}
      </tbody>
    </table>
  );
}

Короткий синтаксис без атрибутов

function ShortSyntax() {
  return (
    <>
      <h1>Title</h1>
      <p>This is a paragraph</p>
      <button>Click me</button>
    </>
  );
}

3. Когда использовать key

В списках и циклах

function TableRows({ data }) {
  return (
    <table>
      <tbody>
        {data.map(item => (
          <React.Fragment key={item.id}>
            <tr>
              <td>{item.title}</td>
              <td>{item.status}</td>
            </tr>
            {item.showDetails && (
              <tr>
                <td colSpan="2">{item.details}</td>
              </tr>
            )}
          </React.Fragment>
        ))}
      </tbody>
    </table>
  );
}

При условном рендеринге в списках

function ConditionalFragments({ items }) {
  return (
    <div>
      {items.map(item => (
        <React.Fragment key={item.id}>
          <h3>{item.title}</h3>
          {item.hasSubtitle && <h4>{item.subtitle}</h4>}
          <p>{item.content}</p>
          {item.showDivider && <hr />}
        </React.Fragment>
      ))}
    </div>
  );
}

4. Практические примеры

Группировка полей формы

function FormFields({ showAdvanced }) {
  return (
    <form>
      <>
        <input type="text" placeholder="Name" />
        <input type="email" placeholder="Email" />
      </>
      
      {showAdvanced && (
        <>
          <input type="tel" placeholder="Phone" />
          <textarea placeholder="Comments" />
        </>
      )}
      
      <button type="submit">Submit</button>
    </form>
  );
}

Множественные элементы в условном рендеринге

function UserProfile({ user, isOwner }) {
  return (
    <div className="profile">
      <img src={user.avatar} alt="Avatar" />
      <h2>{user.name}</h2>
      
      {isOwner && (
        <>
          <button>Edit Profile</button>
          <button>Settings</button>
          <button>Logout</button>
        </>
      )}
    </div>
  );
}

Компоненты высшего порядка

function withLoading(WrappedComponent) {
  return function WithLoadingComponent({ isLoading, ...props }) {
    if (isLoading) {
      return (
        <>
          <div className="spinner" />
          <p>Loading...</p>
        </>
      );
    }
    
    return <WrappedComponent {...props} />;
  };
}

5. Сравнение синтаксисов

СинтаксисАтрибутыИспользование
<React.Fragment>Поддерживает keyКогда нужен key
<>...</>Не поддерживаетПростая группировка
// Когда key НЕ нужен - используйте короткий синтаксис
function SimpleGroup() {
  return (
    <>
      <h1>Header</h1>
      <p>Content</p>
    </>
  );
}
 
// Когда key нужен - используйте полный синтаксис
function ListWithFragments({ items }) {
  return (
    <div>
      {items.map(item => (
        <React.Fragment key={item.id}>
          <h3>{item.title}</h3>
          <p>{item.description}</p>
        </React.Fragment>
      ))}
    </div>
  );
}

6. Альтернативы Fragment

Обычный div (создаёт DOM-узел)

// Создаёт дополнительный div в DOM
function WithDiv() {
  return (
    <div>
      <h1>Title</h1>
      <p>Content</p>
    </div>
  );
}
 
// Не создаёт дополнительный узел
function WithFragment() {
  return (
    <>
      <h1>Title</h1>
      <p>Content</p>
    </>
  );
}

Массив элементов (нужны key)

// Массив - каждому элементу нужен key
function ArrayElements() {
  return [
    <h1 key="title">Title</h1>,
    <p key="content">Content</p>
  ];
}
 
// Fragment - key не нужен
function FragmentElements() {
  return (
    <>
      <h1>Title</h1>
      <p>Content</p>
    </>
  );
}

Лучшие практики

  1. Используйте короткий синтаксис когда key не нужен 🎯
  2. Используйте полный синтаксис когда нужен key 🔑
  3. Предпочитайте Fragment вместо лишних div 📦
  4. Группируйте связанные элементы логически 🧩

Частые ошибки

Неправильно:

// Попытка добавить другие атрибуты
<React.Fragment className="wrapper">
  <div>Content</div>
</React.Fragment>
 
// Использование короткого синтаксиса с key
<key={item.id}>
  <div>{item.name}</div>
</>

Правильно:

// Только key атрибут
<React.Fragment key={item.id}>
  <div>{item.name}</div>
</React.Fragment>
 
// Короткий синтаксис без атрибутов
<>
  <div>Content</div>
</>

Заключение

React Fragment атрибуты:

  • key — единственный поддерживаемый атрибут
  • <React.Fragment> — для использования с key
  • <>…</> — короткий синтаксис без атрибутов
  • Группировка — без создания DOM-узлов

Используйте Fragment для чистой разметки! 🎯