[Перевод] JSX — подробности

Этой публикацией я открываю серию переводов раздела «Продвинутые руководства» (Advanced Guides) официальной документации библиотеки React.js.
JSX — подробности
Фундаментально, JSX является синтаксическим сахаром для функции React.createElement(component, props, ...children).
JSX код:
Click Me
компилируется в:
React.createElement(
MyButton,
{color: 'blue', shadowSize: 2},
'Click Me'
)Также можно использовать самозакрывающую форму для тегов, у которых нет потомков. Например:
компилируется в:
React.createElement(
'div',
{className: 'sidebar'},
null
)Протестировать, как различные конструкции JSX компилируются в JavaScript, можно в онлайн компиляторе Babel
Спецификация типов элементов React
Начальная часть JSX тега определяет тип элемента React.
Типы, определенные с Прописной буквы, указывают на то, что тег ссылается на компонент React. Эти теги в процессе компиляции ссылаются на именованную переменную, содержащую компонент React. Поэтому, обратите внимание, — эта переменная должна находится в области видимости. Например: Если вы используете выражение JSX — , то переменная Foo должна находится в области видимости.
React должен находится в области видимости
Т.к. JSX компилируется в вызовы функции React.createElement, библиотека React всегда должна находиться в области видимости вашего кода JSX.
Например: обе строки import необходимы в данном коде, т.к. React и CustomButton не включены непосредственно в JavaScript:
import React from 'react';
import CustomButton from './CustomButton';
function WarningButton() {
// return React.createElement(CustomButton, {color: 'red'}, null);
return ;
}Если вы не используете какой-либо упаковщик JavaScript и добавляете React непосредственно в тег , то React всегда будет находится в глобальной области видимости.
Использование нотации через точку в JSX типе
На компонент React можно ссылаться используя нотацию через точку в JSX. Это удобно, если у вас есть модуль, который эскпортирует несколько компонентов React. Например, если MyComponents.DatePicker — это компонент, то вы можете использовать эту нотацию непосредственно в JSX:
import React from 'react';
const MyComponents = {
DatePicker: function DatePicker(props) {
return Imagine a {props.color} datepicker here.;
}
}
function BlueDatePicker() {
return ;
}Вновь определенные компоненты, не входящие в стандартную библиотеку React, должны именоваться с Прописной буквы
Если тип элемента именуется со строчной буквы, это означает, что элемент является встроенным компонентом таким как Мы рекомендуем именовать компоненты с Прописной буквы. Если у вас есть компонент, именующийся со строчной буквы, перед использованием в JSX — присвойте его переменной именующейся с Прописной буквы. Для примера, этот код не вернет то, что от него ожидается: Для исправления ошибки, мы переименуем Нельзя использовать общее выражение в типе элемента React. Если вам необходимо использовать общее выражение для определения типа элемента, сначала присвойте его переменной, именованной с Прописной буквы. Это часто необходимо для отображения разных компонентов в зависимости от значения свойства в props: Для исправления ошибки, мы присвоили тип переменной, именуемой с Прописной буквы: Есть несколько различных путей для задания свойств в JSX. Вы можете разместить любое JavaScript выражение в свойстве, заключив его в фигурные скобки Для компонента Инструкции Строковые литералы могут быть размещены в свойствах. Эти два JSX выражения эквивалентны: При размещении строкового литерала — его значение будет HTML деэкранировано. Эти два JSX выражения эквивалентны: Размещение строковых литералов непосредственно в свойствах обычно не используется и дано здесь только для полноты спецификации. Если вы укажете в компоненте JSX свойство и не укажете его значение, то значение свойства по умолчанию установится в Мы не рекомендуем использовать эту возможность, т.к. ее легко спутать с короткой нотацией объектов в ES6 Например: Если у вас есть объект, содержащий свойства, и вы хотите передать его в JSX, вы можете использовать Разворачивание атрибутов может быть полезно при реализации универсальных контейнеров. В то же время, разворачивание может сделать ваш код грязным, т.к. при разворачивании в компонент в качестве свойств передаются все свойства объекта, в том числе те, в которых компонент не нуждается и которые не обрабатывает. Мы рекомендуем использовать данный синтаксис осмотрительно. В JSX выражении, которое содержит открывающий и закрывающий тег, контент, заключенный между этими тегами, при компиляции передается в специальное свойство: Вы можете вставить строку между открывающим и закрывающим тегами и значение Выглядит это так: Это валидное JSX выражение — JSX удаляет пробелы в начале и конце строки. Он также удаляет пустые строки. Переводы строк, примыкающие к тегам будут удалены. Переводы строк, находящиеся в середине строкового литерала и следующие один за другим преобразуются в один перевод строки. Таким образом, следующие примеры будут отображены одинаково: В качестве потомков JSX элемента могут выступать другие JSX элементы. Это удобно для отображения вложенных компонентов: Вы можете смешивать любые типы потомков, будь то строки или JSX элементы. Это еще один вариант когда JSX может выглядеть также как HTML. Следующий пример валиден в JSX и HTML: Компонент React не может возвращать несколько элементов React — иными словами: компонент React всегда должен иметь только один корневой элемент верхнего уровня. Одновременно с этим — одно JSX выражение может иметь неограниченное количество потомков. Таким образом, если у вас нет корневого элемента верхнего уровня — просто оберните свой набор элементов в элемент Вы можете использовать любое JavaScript выражение в качестве потомка, просто взяв его в фигурные скобки — Эта возможность часто используется для отображения списка JSX выражений произвольной длины. Например, этот код отображает список HTML: JavaScript выражения могут совмещаться с другими типами потомков. Это удобно при отображении строковых шаблонов: Как правило, JavaScript выражения, используемые в JSX возвращают строки, элементы React или и то и другое вместе. Однако, В компонент в качестве потомка можно передавать что угодно. Главное — этот компонент должен преобразовать и вернуть к моменту отображения (рендеринга) то, что React знает как отобразить. Такое использование не является общепринятым, но оно прекрасно отображает то, на что способен React. Эта особенность совместно с особенностью обработки условных выражений в JavaScript может быть использована для условного отображения элементов React. Следующее JSX выражение отобразит Однако, есть нюанс, когда некоторые «falsy» значения, такие как число Для исправления ситуации, убедитесь, что выражение перед И наоборот, если вам необходимо отобразить Первоисточник: React — Advanced Guides — JSX In Depth и передается в виде строки 'div' или 'span' в функцию React.createElement. Типы, определенные с прописной буквы, такие как компилируются как React.createElement(Foo) и ссылаются на компонент, определенный или импортированный в вашем JavaScript файле.import React from 'react';
// Неправильно! Это компонент и должен именоваться с Прописной буквы:
function hello(props) {
// Правильно! Использование hello в Hello и будем использовать в JSX: import React from 'react';
// Правильно! Это компонент и именуется с Прописной буквы:
function Hello(props) {
// Правильно! Использование Выбор типа во время выполнения
import React from 'react';
import { PhotoStory, VideoStory } from './stories';
const components = {
photo: PhotoStory,
video: VideoStory
};
function Story(props) {
// Неправильно! JSX тип не может быть выражением.
return import React from 'react';
import { PhotoStory, VideoStory } from './stories';
const components = {
photo: PhotoStory,
video: VideoStory
};
function Story(props) {
// Правильно! JSX тип может быть переменной, именуемой с Прописной буквы.
const SpecificStory = components[props.storyType];
return Свойства в JSX
JavaScript выражения
{}. Например: MyComponent значение props.foo будет 10, т.к. выражение 1 + 2 + 3 + 4 вернет такой результат.if или циклы for не являются выражениями в JavaScript, поэтому они не могут использоваться непосредственно в JSX. Поэтому их необходимо использовать только в окружающем коде. Например: function NumberDescriber(props) {
let description;
if (props.number % 2 == 0) {
description = even;
} else {
description = odd;
}
return Строковые литералы
Свойства по умолчанию принимают значение «True»
true. Эти два JSX выражения эквивалентны: {foo} в ES6 — это короткая нотация записи {foo: foo}, а не {foo: true}. Эта возможность добавлена только из-за ее присутствия в HTML.Разворачивание атрибутов
... в качестве «разворачивающего» (spread) оператора для передачи всех свойств, содержащихся в объекте. Эти два компонента эквивалентны: function App1() {
return Потомок (children) в JSX
props.children. Давайте рассмотрим типы возможных потомков: Строковые литералы
props.children будет равно этой строке. Использование строковых литералов удобно для многих встроенных элементов HTML. props.children компонента MyComponent установится равным строке "Hello world!". Обратите внимание, что значение строкового литерала будет HTML деэкранировано при компиляции, поэтому в общем упрощенном случае вы можете писать свой JSX код также как вы пишете HTML: JSX элемент
div, как в предыдущем примере.JavaScript выражения
{}. Например, следующие выражения эквивалентны: function Item(props) {
return
{todos.map((message) =>
);
}function Hello(props) {
return Функции JavaScript
props.children работает также как и любое другое свойство, в которое можно передать любой вид данных, а не только данные тех типов, которые React знает как отобразить. Например, вы можете определить некий компонент, и принять от него обратный вызов через props.children: function ListOfTenThings() {
return (
Булевые значения, Null и Undefined игнорируются
false, null, undefined и true можно использовать в качестве потомков. Но данные значения не отображаются при рендеринге. Следующие JSX выражения будут отображены одинаково:
если значение showHeader будет true: 0, отображаются React. Например, следующий код не будет вести себя как ожидается, и в случае если props.messages будет содержать пустой массив — в результате рендеринга будет отображен 0: && всегда является булевым: false, true, null или undefined при рендеринге — сконвертируйте их в строку:
Комментарии (0)
