С одной стороны, JSX — это такая же простая вещь, как и голый HTML. Нужно запомнить, как он собирается и всё. С другой стороны, он встроен в сам JS и может с ним взаимодействовать. Другими словами, получается шаблонизация прямо в языке программирования (да-да, так работает PHP). Именно это смешение с JS вызывает больше всего вопросов у новичков. Попробуем разобраться с этой темой подробнее.
Для лучшего понимания происходящего, проверьте во что транслируется код этого урока в онлайн компиляторе https://babeljs.io/repl
Любой текст, записанный внутри тегов (далее они будут так называться для простоты), остаётся просто статическим текстом на выводе. А что делать, если нужно вставить значение переменной? Ответ ниже:
const name = 'Eva';
const cname = 'container';
const vdom1 = <div>Hello, {name}</div>;
const vdom2 = <div>Hello, {name.repeat(3)}</div>;
const vdom3 = <div className={cname}>Hello!</div>;
Как видно, вставка (по сути — интерполяция) происходит за счёт использования фигурных скобок, причём внутри них может быть любое выражение. Эта схема работает одинаково как для содержимого тегов, так и для атрибутов.
Кроме того, сами JSX-элементы являются выражениями, то есть вы можете использовать их в любых местах JS-кода, которые работают с выражениями:
const name = 'Mike';
const vdom = block ? <div>hello, {name}</div> : <span>i am span</span>;
Теперь всё вместе. Сам JSX — это выражение, а чтобы встроить выражение на JS внутрь JSX, нужно использовать фигурные скобки. Следовательно, вы можете встроить JSX внутрь самого JSX пока вы пишете JSX:
const vdom = <div>
{isAdmin ? <p><a href="#">{text}</a></p> : <p>{text}</p>}
<Hello />
</div>;
Другими словами, JSX, как и любой язык программирования, имеет рекурсивную структуру. Вы можете вкладывать одни выражения в другие до бесконечности. В этом нет ничего удивительного, ведь JSX — это тот же код на JS, записанный особым образом.
Чтобы окончательно закрепить эту тему, взгляните на следующий код:
<div id={if (condition) { 'msg' }}>Hello World!</div>
Этот код не заработает по очевидной причине. Условная конструкция в JS — инструкция, а не выражение. В результате компиляции предыдущего кода получится:
React.createElement("div", {id: if (condition) { 'msg' }}, "Hello World!");
И это, вероятно, самое большое неудобство: невозможность использовать условную конструкцию внутри JSX. Хотя вы по-прежнему можете использовать тернарную операцию или, в более сложных случаях, делать так:
let button;
if (loggedIn) {
button = <LogoutButton />;
} else {
button = <LoginButton />;
}
return (
<nav>
<Home />
{button}
</nav>
);
Композиция
Как уже говорилось в прошлом уроке, все теги React по сути являются встроенными компонентами, которые работают точно так же, как и определённые вами. А значит все, что применимо к самописным компонентам, также применимо и ко встроенным. Обратное тоже верно. На практике это означает, например, возможность комбинирования компонентов:
const vdom = (
<div>
<Hello />
<Hello />
<AnotherComponent>
<p>What is love</p>
</AnotherComponent>
</div>
);
В примере выше компоненты, записанные с заглавной буквы, — самописные, остальные — встроенные. Это разделение не случайно: React требует, чтобы вновь создаваемые компоненты начинались с большой буквы, что соответствует стандарту именования классов в JS.
Null
В реальной практике возникают ситуации, когда наличие того или иного компонента в DOM зависит от некоторых условий. Например, если в компонент не передали текст, то и не надо выводить соответствующий кусок. Пример:
const header = text ? <h1>{text}</h1> : null;
const vdom = (
<div>
{header}
<Hello />
</div>
);
либо так:
const vdom = (
<div>
{text ? <h1>{text}</h1> : null}
<Hello />
</div>
);
То есть null
— это допустимое значение, которое рассматривается React как пустой компонент. Точно также интерпретируются false
, true
и undefined
. Поэтому пример выше можно переписать еще короче.
const vdom = (
<div>
{text && <h1>{text}</h1>}
<Hello />
</div>
);
Комментарии
JSX не поддерживает комментарии напрямую, но их можно эмулировать, используя JavaScript. Для этого достаточно вставить блок кода, внутри которого однострочный JavaScript комментарий:
{/* A JSX comment */}
То же самое для многострочного комментария:
{/*
Multi
line
comment
*/}
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.