К содержанию

JSX: разметка внутри JavaScript

Выражения, скобки return, фрагменты и отличия от HTML.

На этой странице

Для Next.js 16.3.8 (App Router) и React 19.3.0. Обновлено .

В HTML мы описывали страницу в отдельном файле. JSX позволяет записать похожую разметку внутри JavaScript или TypeScript и подставить в неё значения. Это синтаксис React, а не строка с HTML.

Подставляем значение

Самостоятельный пример заменяет app/page.tsx:

app/page.tsx
export default function HomePage() {
  const title = "Кинопоказ";
  const price = 300;
 
  return (
    <article>
      <h1>{title}</h1>
      <p>Два билета: {price * 2} ₽</p>
    </article>
  );
}

В {title} берется строка из переменной. В {price * 2} вычисляется выражение, поэтому появится 600 ₽. Если написать title без фигурных скобок, на странице появится само слово «title».

В фигурных скобках должно быть выражение, которое возвращает значение: переменная, вычисление или вызов функции. Инструкцию if прямо туда поставить нельзя. Выполните проверку до return или используйте условное выражение из следующей статьи.

Что возвращает компонент

Короткая запись может занимать одну строку:

app/page.tsx
export default function HomePage() {
  return <h1>Куда пойти</h1>;
}

Если JSX занимает несколько строк, оберните его круглыми скобками. Открывающую скобку поставьте на той же строке, что и return. Иначе JavaScript может завершить инструкцию на переносе строки, и функция вернет undefined.

app/page.tsx
// Верно: выражение начинается на строке return.
return (
  <h1>Куда пойти</h1>
);
 
// Ошибка: разметка не станет возвращаемым результатом.
return
  <h1>Куда пойти</h1>;

Во втором фрагменте перенос завершает инструкцию: получается return;, поэтому функция не возвращает разметку. Это сравнение внутри функции, не полный файл.

Стрелочная функция тоже может возвращать JSX: const Title = () => <h1>Куда пойти</h1>. Если её тело заключено в { }, результат нужно вернуть через return. Для начала используем обычные именованные функции.

Один корень и фрагмент

Соседние элементы объединяют общим корнем. Когда дополнительный HTML-контейнер не нужен, используйте фрагмент <>...</>:

app/page.tsx
export default function HomePage() {
  return (
    <>
      <h1>Куда пойти</h1>
      <p>Выберите мероприятие.</p>
    </>
  );
}

Фрагмент группирует результат компонента, но не добавляет div в DOM. Это пустые угловые скобки специального синтаксиса JSX, а не новый HTML-тег. Компонент также может вернуть null, если ему сейчас нечего показывать.

Отличия от HTML

Обычный HTMLJSXПричина
class="card"className="card"Имя свойства элемента в React
for="email"htmlFor="email"Связь подписи с полем
<br><br />В JSX элементы закрываются
style="padding: 16px"style={{ padding: 16 }}Стиль передается объектом

В style={{ ... }} внешние скобки вставляют выражение JavaScript, внутренние создают объект. Составные имена свойств записываются как backgroundColor, а не background-color. Для многих размеров React добавляет px к числу; безразмерные свойства вроде opacity остаются числами.

app/page.tsx
export default function HomePage() {
  const imageUrl = "/poster.jpg";
 
  return (
    <article className="card" style={{ padding: 16 }}>
      <img src={imageUrl} alt="Афиша кинопоказа" />
    </article>
  );
}

Положите свою картинку в public/poster.jpg. Адрес /poster.jpg считается от корня сайта. Строку можно записать в кавычках. Переменную или выражение передают через { }. Позже для оптимизации изображений можно перейти к next/image.

Для комментария внутри JSX используется {/* пояснение */}. Обычный // между тегами не обозначает комментарий JSX.

Попробуйте сами

Покажите название мероприятия из переменной, вычислите стоимость трех билетов и добавьте изображение с понятным alt. Перепишите результат сначала с main, затем с фрагментом. Проверьте DOM: во второй версии дополнительной обертки быть не должно.

Далее – компоненты и параметры. Официальные объяснения: правила JSX, выражения в JSX.