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


Рассмотрим следующий код:


Код
    
    const element = <h1>Hello, world!</h1>;
    

Этот симпатичный синтаксис в виде тегов не является ни строкой, ни HTML. Это синтаксический сахар JavaScript под названием JSX. Мы настоятельно рекомендуем использовать JSX вместе с React, так как он максимально ясно описывает внешний вид UI, одновременно включая в себя всю мощь JavaScript.

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



2.3.1 Почему JSX?


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

Вместо того, чтобы искусственно отделять технологии, помещая разметку и логику в отдельные файлы, React разделяет задачи. Для этого он использует слабо связанные единицы: компоненты, которые содержат и разметку, и логику. Мы вернемся к компонентам в следующем разделе. Если же вас не устраивает помещение разметки в JS, данное обсуждение может поменять вашу точку зрения.

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

Итак, давайте приступим!



2.3.2 Встраиваемые выражения в JSX


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


Код
    
    const name = 'Вася Пупкин';
    const element = <h1>Привет, {name}</h1>;

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

Вы можете встроить любое JavaScript выражение в JSX, его нужно лишь обернуть в фигурные скобки.

Например, 2 + 2, user.firstName, и formatName(user) – все являются корректными выражениями.

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


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

    const user = {
      firstName: 'Harper',
      lastName: 'Perez'
    };

    // улучшаем читабельность
    const element = (
      <h1>
        Hello, {formatName(user)}!
      </h1>
    );

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

Посмотреть в CodePen


Здесь мы поделили выражение JSX на несколько линий для читабельности. Хоть это и не обязательно, мы рекомендуем оборачивать JSX-выражения в круглые скобки () во избежание подводных камней автоматической вставки точки с запятой



2.3.3 JSX сам является выражением


После компиляции JSX-выражения становятся обычными JavaScript-объектами.



Это означает, что вы можете использовать JSX внутри условного оператора if и оператора цикла for, присваивать его переменным, принимать как аргумент и возвращать из функций. В общем, можно делать все то, что и с обычным JavaScript-объектом:


Код
    
    function getGreeting(user) {
      if (user) {
        return <h1>Hello, {formatName(user)}!</h1>;
      }
      return <h1>Hello, Stranger.</h1>;
    }
    



2.3.4 Указание атрибутов с помощью JSX


Мы можем использовать двойные кавычки для указания строковых литералов как атрибутов:


Код
    
    const element = <div tabIndex="0"></div>;
    

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


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

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


Предостережение!

Так как JSX ближе к JavaScript, чем к HTML, React DOM использует соглашение об именовании свойств в верблюжьейНотации, вместо имен HTML-атрибутов.

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



2.3.5 Указание потомков с помощью JSX


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


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

Однако JSX-теги могут иметь потомков:


Код
    
    const element = (
        <div>
            <h1>Hello!</h1>
            <h2>Good to see you here.</h2>
        </div>
    );
    



2.3.6 JSX предотвращает атаки инъекцией


Как насчет пользовательского ввода? Об этом разработчики React также побеспокоились. В JSX можно встроить любой результат ввода пользователя и это будет абсолютно безопасно!


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

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



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


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

Эти два примера эквивалентны:


Код
    
    const element = (
      <h1 className="greeting">
        Hello, world!
      </h1>
    );
    


Код
    
    const element = React.createElement(
      'h1',
      {className: 'greeting'},
      'Hello, world!'
    );
    

React.createElement() выполняет несколько проверок, чтобы помочь вам написать свободный от багов код, но по существу он создает объект наподобие следующего:


Код
    
    // Обратите внимание: эта структура упрощена
    const element = {
      type: 'h1',
      props: {
        className: 'greeting',
        children: 'Hello, world'
      }
    };
    

А если зайти в исходники, то этот объект будет выглядеть так:


Код
    
    var element = {
      // This tag allow us to uniquely identify this as a React Element
      $$typeof: REACT_ELEMENT_TYPE,

      // Built-in properties that belong on the element
      type: type,
      key: key,
      ref: ref,
      props: props,

      // Record the component responsible for creating this element.
      _owner: owner,
    };
    

Полный исходный код можно посмотреть здесь.

Данные объекты носят название «React-элементы». Вы можете представлять себе такой объект, как описание того, что вам необходимо увидеть на экране. React читает эти объекты, использует их для построения дерева DOM и хранит их в актуальном состоянии.


Подсказка!

Мы рекомендуем использовать Babel language definition для вашего редактора, чтобы ES6 и JSX подсвечивались корректно.