Перейти к содержанию

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

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

1
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, обрамляя фигурными скобками:

1
2
3
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>:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
function formatName(user) {
  return user.firstName + ' ' + user.lastName
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1
2
3
4
5
6
const element = (
  <div>
    <h1>Здравствуйте!</h1>
    <h2>Рады вас видеть.</h2>
  </div>
)

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

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

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

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

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

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

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

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

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

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

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

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

Совет:

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

Комментарии