3. JSX синтаксис
React: JSX Синтаксис
Заголовок раздела «React: JSX Синтаксис»
Что такое JSX? Концепция
Заголовок раздела «Что такое JSX? Концепция»JSX (JavaScript XML) — это расширение синтаксиса JavaScript, которое позволяет описывать структуру пользовательского интерфейса (UI) способом, очень похожим на HTML. Это не обязательная, но крайне рекомендуемая часть разработки на React, значительно улучшающая читаемость и написание кода.
Представьте, что вы пишете HTML внутри JavaScript. Это и есть JSX!
Зачем использовать JSX?
- Декларативность: Описание UI становится более интуитивным и легким для понимания.
- Знакомый синтаксис: Разработчикам, знакомым с HTML, очень легко адаптироваться.
- Повышенная безопасность: JSX предотвращает инъекции (XSS) по умолчанию, поскольку он преобразует все значения, вложенные в JSX, в строки перед рендерингом.
- Производительность: Babel компилирует JSX в оптимизированные вызовы
React.createElement(), что React может использовать для построения эффективного виртуального DOM.
Важно понимать, что браузеры не понимают JSX напрямую. Ваш код на JSX транспилируется (обычно с помощью Babel) в обычный JavaScript-код (вызовы React.createElement()) перед тем, как браузер его выполнит.
Базовый Принцип Работы и Примеры
Заголовок раздела «Базовый Принцип Работы и Примеры»1. JSX Элементы и Атрибуты
Заголовок раздела «1. JSX Элементы и Атрибуты»JSX очень похож на HTML, но есть несколько ключевых отличий.
// Простой JSX элементconst greeting = <h1>Привет, React!</h1>;
// JSX элемент с атрибутами (обратите внимание на className вместо class)const button = <button className="my-button" onClick={() => alert('Нажата!')}> Нажми меня</button>;
// Самозакрывающийся тегconst image = <img src="logo.png" alt="React Logo" />;
// Несколько элементов должны быть обернуты в один родительский элемент (или фрагмент)const appContent = ( <div> {greeting} {button} {image} </div>);2. Внедрение JavaScript-выражений
Заголовок раздела «2. Внедрение JavaScript-выражений»Вы можете вставлять любые JavaScript-выражения в JSX, используя фигурные скобки {}.
const userName = 'Студент';const userId = 123;const isActive = true;
const userInfo = ( <div> <h2>Пользователь: {userName}</h2> {/* Переменная */} <p>ID: {userId * 2}</p> {/* Арифметическое выражение */} <p>Статус: {isActive ? 'Активен' : 'Неактивен'}</p> {/* Тернарный оператор */} <p>Дата: {new Date().toLocaleDateString()}</p> {/* Вызов функции */} </div>);3. Комментарии в JSX
Заголовок раздела «3. Комментарии в JSX»Комментарии внутри JSX пишутся как JavaScript-комментарии, но обернутые в фигурные скобки.
const productCard = ( <div> {/* Это комментарий внутри JSX */} <h3>Название продукта</h3> {/* <p>Этот параграф не будет отображен, так как он закомментирован как элемент</p> */} <p>Цена: 19.99</p> </div>);JSX в Функциональных Компонентах с Hooks
Заголовок раздела «JSX в Функциональных Компонентах с Hooks»Современный React использует функциональные компоненты и хуки. JSX является неотъемлемой частью их работы.
import React, { useState } from 'react';
type CounterProps = { initialValue?: number;};
function Counter({ initialValue = 0 }: CounterProps) { const [count, setCount] = useState(initialValue);
return ( <div style={{ padding: '20px', border: '1px solid gray' }}> <h2>Счетчик: {count}</h2> <button onClick={() => setCount(count + 1)}> Увеличить </button> <button onClick={() => setCount(count - 1)} style={{ marginLeft: '10px' }}> Уменьшить </button> {/* Условный рендеринг на основе значения count */} {count % 2 === 0 && <p>Число четное!</p>} {count === 5 && <p>Достигнуто 5!</p>} </div> );}
// Пример использования:// <Counter initialValue={10} />Оптимизация и Расширенные Приемы JSX
Заголовок раздела «Оптимизация и Расширенные Приемы JSX»1. Фрагменты (<></> или <React.Fragment>)
Заголовок раздела «1. Фрагменты (<></> или <React.Fragment>)»JSX-элемент должен иметь только один корневой элемент. Если вам нужно вернуть несколько элементов без лишней обертки, используйте Фрагменты.
// Ошибка: Возвращает несколько корневых элементов// function MyComponent() {// return (// <p>Первый параграф</p>// <p>Второй параграф</p>// );// }
// Правильно: Использование сокращенного синтаксиса фрагментаfunction MyComponent() { return ( <> <p>Первый параграф</p> <p>Второй параграф</p> </> );}
// Альтернатива с явным React.Fragment (полезно, если нужен атрибут key)function AnotherComponent() { return ( <React.Fragment> <span>Элемент 1</span> <span>Элемент 2</span> </React.Fragment> );}2. Рендеринг Списков (map с key)
Заголовок раздела «2. Рендеринг Списков (map с key)»При рендеринге списков элементов с помощью метода map, каждый элемент должен иметь уникальный key пропс. Это помогает React эффективно обновлять списки.
const items = ['Яблоко', 'Банан', 'Вишня'];
function ShoppingList() { return ( <ul> {items.map((item, index) => ( // Key должен быть уникальным среди соседних элементов. // Лучше использовать ID из данных, если они есть. index - как крайняя мера. <li key={index}>{item}</li> ))} </ul> );}Типичные Ошибки в JSX
Заголовок раздела «Типичные Ошибки в JSX»- Несколько корневых элементов без обертки:
// НЕПРАВИЛЬНО// return <p>Привет</p><p>Мир</p>;// ПРАВИЛЬНОreturn <> <p>Привет</p><p>Мир</p> </> ;
- Использование
classвместоclassName: HTML-атрибутclassв JSX конфликтует с зарезервированным словом JavaScript, поэтому используетсяclassName. - Использование
forвместоhtmlFor: Аналогично,forв JSX заменяется наhtmlForдля связи label с input. - Забывание
keyпри рендеринге списков: Может привести к проблемам с производительностью и некорректному поведению UI. - Попытка использовать HTML-комментарии
<!-- -->внутри JSX: Используйте{/* */}для комментариев внутри JSX. - Вставлять объекты в JSX напрямую (кроме исключений, как стили):
const myObject = { name: 'Alice' };// НЕПРАВИЛЬНО: <div>{myObject}</div> -- React не знает, как рендерить объект.// ПРАВИЛЬНО: <div>{myObject.name}</div>
Практика
Заголовок раздела «Практика»Создайте функциональный компонент UserCard, который принимает пропсы name, age и email. Компонент должен отображать эту информацию внутри div, используя JSX. Добавьте условный рендеринг, чтобы отображать текст “Совершеннолетний”, если возраст пользователя 18 или больше.
Попробуйте изменить код прямо здесь и увидите результат справа! 👇