React JSX

JSX (JavaScript XML) — это расширение синтаксиса JavaScript, которое выглядит как XML. В React его часто используют вместо обычного JavaScript для написания UI-компонентов, что позволяет описывать структуру и поведение компонентов HTML-подобным способом.

Использование JSX не обязательно, но у него есть следующие ключевые преимущества:

  • Эффективное выполнение: после компиляции в код JavaScript он оптимизируется и работает быстрее;
  • Типобезопасность: ошибки можно обнаружить на этапе компиляции (что ещё лучше с TypeScript);
  • Удобное написание: структура UI интуитивно понятна и ясна, встраивание выражений JavaScript более гибкое, а написание шаблонов простое и быстрое;
  • Суть: это не строка/HTML; Babel (встроенный в Vite) компилирует это в вызовы React.createElement.

Давайте сначала посмотрим на следующий код:

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

Этот кажущийся странным синтаксис тегов не является ни строкой, ни HTML.

Он называется JSX — синтаксическое расширение JavaScript. Мы рекомендуем использовать JSX в React для описания пользовательских интерфейсов.

JSX реализован внутри JavaScript.

Мы знаем, что элементы — это наименьшие единицы, из которых состоит приложение React, а JSX используется для объявления элементов в React.

В отличие от элементов DOM браузера, элементы в React на самом деле являются обычными объектами. React DOM гарантирует, что содержимое данных DOM браузера остаётся согласованным с элементами React.

Чтобы отобразить элементы React в корневой DOM-узел, мы передаём их все в ReactDOM.render() для отображения на странице:

Пример React

const element = <h1 className="foo">Привет, мир</h1>; const root = ReactDOM.createRoot(document.getElementById("root")); root.render(element);

Попробуйте »

Примечание:

Поскольку JSX — это JavaScript, некоторые идентификаторы, такие какclassиforне рекомендуются в качестве XMLclassNameиhtmlForимён атрибутов. Вместо этого React DOM использует


Правила синтаксиса JSX

Правила синтаксиса JSX

JSX выглядит как HTML, но имеет строгие правила:

  • HTML может<br>, но JSX должен<br />(самозакрывающийся).
  • Все теги должны быть закрыты:<div></div>。

class → className:

Поскольку class — это ключевое слово JavaScript, вместо него используйте className.

<div className="container">内容</div>

htmlFor (внутри label):

<label for="id"> → <label htmlFor="id">

Компоненты, начинающиеся с заглавной буквы:

Пользовательские компоненты должны начинаться с заглавной буквы (строчные будут восприниматься как HTML-теги).

<Card />  {/* 正确,自定义组件 */}
<card />  {/* 错误,会被当成 <card> HTML 标签 */}

Комментарии:

используйте{/* comment content */}。

jsx{/* 这是一个 JSX 注释 */}

Корневой элемент:

return может иметь только один корневой узел.

return (
  <>  {/* 碎片 Fragment,空标签,不渲染 DOM */}
    <h1>标题</h1>
    <p>段落</p>
  </>
);

Мы можем открыть src/App.jsx и изменить return на:

return (
  <>
    <h1 className="title">JSX 语法规则演示</h1>
    <img src="../vite.svg.html" alt="Vite Logo" />
    <br />
    {/* 自闭合标签和注释 */}
    <p>注意 className 和闭合标签</p>
  </>
);

Сохраните, чтобы увидеть эффект.


Встраивание выражений, условный рендеринг, рендеринг списков

Самая мощная особенность JSX в том, что с помощью {} можно встраивать JavaScript-выражения (только выражения, а не инструкции вроде if/for).

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

Любое допустимое JS-выражение можно поместить внутрь{}:

const name = 'example';
const now = new Date().toLocaleString();

return (
  <div>
    <h1>你好,{name}!</h1>
    <p>当前时间:{now}</p>
    <p>计算结果:{2 + 3 * 5}</p>  {/* 17 */}
  </div>
);

Условный рендеринг

Используйте тернарные операторы или&&:

const isLoggedIn = true;
const count = 0;

return (
  <div>
    {isLoggedIn ? <h1>欢迎回来,{name}!</h1> : <h1>请登录</h1>}
    
    {count > 0 && <p>你有 {count} 条未读消息</p>}  {/* count 为 0 时不渲染 */}
  </div>
);

Избегайте:Не используйте операторы if напрямую в JSX (их можно использовать внутри тел функций).

Рендеринг списков (важность key)

Используйте map() для рендеринга массивов. Необходимо добавить атрибут key каждому элементу (уникальный идентификатор, который помогает React эффективно обновлять DOM).

const items = [
  { id: 1, name: '苹果' },
  { id: 2, name: '香蕉' },
  { id: 3, name: '橙子' },
];

return (
  <ul>
    {items.map(item => (
      <li key={item.id}>  {/* key 必须唯一且稳定! */}
        {item.name}
      </li>
    ))}
  </ul>
);

Важность key:

  • Без key: React выдаст предупреждение, что может вызвать ошибки рендеринга (особенно когда список изменяется динамически).
  • Плохая привычка: использовать index в качестве key (key={index}) — когда порядок списка меняется, это может вызвать ненужные повторные рендеры или потерю состояния.
  • Лучшая практика: использовать уникальный ID из данных (например, id из базы данных).

Стилизация

В React есть несколько подходов к стилизации; давайте сначала изучим два самых базовых.

Встроенные стили

Используйте атрибут style, значение которого — объект (camelCase):

return (
  <div
    style={{
      backgroundColor: '#F0F0F0',
      padding: '20px',
      borderRadius: '8px',
      textAlign: 'center',
      fontFamily: 'Arial, sans-serif',
    }}
  >
    <h2 style={{ color: 'blue', marginBottom: '10px' }}>
      内联样式示例
    </h2>
  </div>
);
  • Преимущество: динамические стили просты (можно использовать переменные).
  • Недостаток: неудобно поддерживать сложные стили.

CSS Modules (рекомендуется, локальная изоляция)

Vite поддерживает CSS Modules по умолчанию, избегая глобального загрязнения.

Создайте src/App.css (уже существует) или новый файл src/styles/Card.module.css:

/* Card.module.css */
.card {
  background: white;
  border-radius: 12px;
  box-shadow: 0 4px 12px rgba(0,0,0,0.1);
  padding: 20px;
  margin: 20px;
}

.title {
  color: #333;
  margin: 0 0 10px 0;
}

.content {
  color: #666;
}

Импортируйте и используйте его в компоненте (имена классов с локальной областью видимости генерируются автоматически):

import styles from './styles/Card.module.css';

return (
  <div className={styles.card}>
    <h3 className={styles.title}>标题</h3>
    <p className={styles.content}>内容</p>
  </div>
);
  • Преимущество: имена классов автоматически хешируются (например, .card__abc123), поэтому конфликтов не возникает.

Полная практика:Измените предыдущий компонент Card, чтобы он использовал CSS Modules.

Создайте src/components/Card.module.css:

.container {
  width: 300px;
  border: 1px solid #ccc;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 4px 12px rgba(0,0,0,0.1);
  background: white;
}

.image {
  width: 100%;
  height: 200px;
  object-fit: cover;
}

.title {
  margin: 0 0 10px 0;
  padding: 20px 20px 0;
  color: #333;
}

.content {
  padding: 0 20px 20px;
  color: #666;
}

Измените Card.jsx:

import styles from './Card.module.css';

const Card = ({ title, content, imageUrl }) => {
  return (
    <div className={styles.container}>
      {imageUrl && <img src={imageUrl} alt={title} className={styles.image} />}
      <h3 className={styles.title}>{title}</h3>
      <p className={styles.content}>{content}</p>
    </div>
  );
};

export default Card;

Использование JSX

JSX выглядит похоже на HTML; можно посмотреть пример:

const element = <h1 className="foo">Привет, мир</h1>; const root = ReactDOM.createRoot(document.getElementById("root")); root.render(element);

Мы можем вложить несколько HTML-тегов в приведённый выше код, и их нужно обернуть элементом div. У элемента p в примере есть пользовательский атрибутdata-myattribute, чтобы добавить пользовательские атрибуты, нужно использоватьdata-префикс.

Пример React

const root = ReactDOM.createRoot(document.getElementById("root")); root.render( <div> <h1>Учебник для новичков</h1> <h2>Добро пожаловать в изучениеReact</h2> <p data-myattribute = "somevalue">Это очень хорошаяJavaScriptБиблиотека!\p> </div> );

Попробуйте »

Отдельный файл

Ваш код React JSX можно разместить в отдельном файле, например, мы создаёмhelloworld_react.jsфайл, код выглядит следующим образом:

const element = <h1 className="foo">Привет, мир</h1>; const root = ReactDOM.createRoot(document.getElementById("root")); root.render(element);

Затем подключите JS-файл к HTML-файлу:

Пример React

<body> <div id="example"></div> <script type="text/babel" src="helloworld_react.js"></script> </body>

Попробуйте »

Выражения JavaScript

Мы можем использовать выражения JavaScript в JSX. Выражения записываются в фигурных скобках{}внутри. Пример выглядит так:

Пример React

const root = ReactDOM.createRoot(document.getElementById("root")); root.render( <div> <h1>{1+1}</h1> </div> );

Попробуйте »

В JSX нельзя использоватьif elseинструкции, но можно использоватьусловное (тернарная операция)выражение вместо этого. В следующем примере, если переменнаяiравна1браузер выведетtrue, если значение i изменить, он выведетfalse.

Пример React

var i = 1; const root = ReactDOM.createRoot(document.getElementById("root")); root.render( <div> <h1>{i == 1 ? 'True!' : 'False'}</h1> </div> );

Попробуйте »

Стили

React рекомендует использовать встроенные стили. Мы можем использоватьcamelCaseсинтаксис для задания встроенных стилей. React автоматически добавит после указанного числа элементаpx. Следующий пример демонстрирует дляh1элемента добавлениеmyStyleвстроенного стиля:

Пример React

var myStyle = { fontSize: 100, color: '#FF0000' }; const root = ReactDOM.createRoot(document.getElementById("root")); root.render( <h1 style = {myStyle}>Учебник для новичков</h1> );

Попробуйте »

Комментарии

Комментарии нужно писать в фигурных скобках, например:

Пример React

const root = ReactDOM.createRoot(document.getElementById("root")); root.render( <div> <h1>Учебник для новичков</h1> {/*comment...*/} </div> );

Попробуйте »

Массивы

JSX позволяет вставлять массивы в шаблоны, и массив автоматически разворачивает все элементы:

Пример React

var arr = [ <h1>Учебник для новичков</h1>, <h2>То, что мы изучаем — не только технологии, но и мечты!</h2>, ]; const root = ReactDOM.createRoot(document.getElementById("root")); root.render( <div>{arr}</div> );

Попробуйте »
Другие расширения