Знакомство с JSX

Рассмотрим объявление переменной:

const element = <h1>Привет, мир!</h1>;

Этот странный тег — ни строка, ни фрагмент HTML.

Это JSX — расширение языка JavaScript. Мы рекомендуем использовать его, когда требуется объяснить React, как должен выглядеть UI. JSX напоминает язык шаблонов, наделённый силой JavaScript.

JSX производит «элементы» React. То, как элементы рендерятся в DOM, мы изучим в следующей главе, а ниже мы рассмотрим основы JSX, которые нужно знать начинающему.

Что такое JSX?

React исходит из принципа, что логика рендеринга неразрывно связана с прочей логикой UI: с тем, как обрабатываются события, как состояние изменяется во времени и как данные готовятся к отображению.

Вместо того, чтобы искусственно разделить технологии, помещая разметку и логику в разные файлы, React разделяет ответственность с помощью слабо связанных единиц, называемых «компоненты», которые содержат и разметку, и логику. Мы ещё вернёмся к теме компонентов в следующей главе, но если идея держать разметку в JavaScript коде всё ещё вызывает у вас дискомфорт, этот доклад может переубедить вас.

React можно использовать и без JSX, но большинство людей ценит его за наглядность при работе с UI, живущем в JavaScript-коде. Помимо этого, JSX помогает React делать сообщения об ошибках и предупреждениях понятнее.

С этим разобрались. Поехали дальше!

Встраивание выражений в JSX

В следующем примере мы объявляем переменную name и затем используем её внутри JSX, обрамляя фигурными скобками:

const name = 'Иван-Царевич';const element = <h1>Здравствуй, {name}!</h1>;
ReactDOM.render(
  element,
  document.getElementById('root')
);

JSX допускает использование любых корректных JavaScript-выражений внутри фигурных скобок. Например, 2 + 2, user.firstName и formatName(user) являются допустимыми выражениями.

В примере ниже мы встраиваем результат вызова JavaScript-функции formatName(user) в элемент <h1>:

function formatName(user) {
  return user.firstName + ' ' + user.lastName;
}

const user = {
  firstName: 'Марья',
  lastName: 'Моревна'
};

const element = (
  <h1>
    Здравствуй, {formatName(user)}!  </h1>
);

ReactDOM.render(
  element,
  document.getElementById('root')
);

Посмотреть на CodePen

Чтобы улучшить читаемость, мы разбили JSX на несколько строк. В таких случаях, хотя это и не обязательно, мы советуем заключать всё выражение целиком в круглые скобки, чтобы избежать проблем, связанных с автоматической вставкой точек с запятой.

JSX это тоже выражение

После компиляции каждое JSX-выражение становится обычным вызовом JavaScript-функции, результат которого — объект JavaScript.

Из этого следует, что JSX можно использовать внутри выражений if и циклов for, присваивать переменным, передавать функции в качестве аргумента и возвращать из функции.

function getGreeting(user) {
  if (user) {
    return <h1>Здравствуй, {formatName(user)}!</h1>;  }
  return <h1>Здравствуй, незнакомец.</h1>;}

Использование атрибутов JSX

Чтобы использовать строковый литерал в качестве значения атрибута, используются кавычки:

const element = <div tabIndex="0"></div>;

Если же в значении атрибута требуется указать JavaScript-выражение, то на помощь приходят фигурные скобки:

const element = <img src={user.avatarUrl}></img>;

Не ставьте кавычек вокруг фигурных скобок, когда используете JavaScript-выражение в значении атрибута. Следует либо применить кавычки (для строковых литералов), либо фигурные скобки (для выражений), но не то и другое вместе.

Предупреждение:

Поскольку JSX ближе к JavaScript чем к HTML, React DOM использует стиль именования camelCase для свойств вместо обычных имён HTML-атрибутов.

Например, class становится className в JSX, а tabindex становится tabIndex.

Использование дочерних элементов в JSX

Если тег пуст, то его можно сразу же закрыть с помощью /> точно так же, как и в XML:

const element = <img src={user.avatarUrl} />;

Но JSX-теги могут и содержать дочерние элементы:

const element = (
  <div>
    <h1>Здравствуйте!</h1>
    <h2>Рады вас видеть.</h2>
  </div>
);

JSX предотвращает атаки, основанные на инъекции кода

Данные, введённые пользователем, можно безопасно использовать в JSX:

const title = response.potentiallyMaliciousInput;
// Этот код безопасен:
const element = <h1>{title}</h1>;

По умолчанию React DOM экранирует все значения, включённые в JSX перед тем как отрендерить их. Это гарантирует, что вы никогда не внедрите чего-либо, что не было явно написано в вашем приложении. Всё преобразуется в строчки, перед тем как быть отрендеренным. Это помогает предотвращать атаки межсайтовым скриптингом (XSS).

JSX представляет собой объекты

Babel компилирует JSX в вызовы React.createElement().

Следующие два примера кода эквивалентны между собой:

const element = (
  <h1 className="greeting">
    Привет, мир!
  </h1>
);
const element = React.createElement(
  'h1',
  {className: 'greeting'},
  'Привет, мир!'
);

React.createElement() проводит некоторые проверки с целью выявить баги в коде, но главное — создаёт объект похожий на такой:

// Примечание: этот код несколько упрощён.
const element = {
  type: 'h1',
  props: {
    className: 'greeting',
    children: 'Привет, мир!'
  }
};

Эти объекты называются React-элементами. Можно сказать, что они описывают результат, который мы хотим увидеть на экране. React читает эти объекты и использует их, чтобы конструировать и поддерживать DOM.

В следующей главе мы углубимся в то, как React элементы рендерятся в DOM.

Совет:

Мы рекомендуем настроить ваш любимый редактор кода использовать Babel чтобы и ES6, и JSX код были подсвечены должным образом.