Почему до React 17 требовалось импортировать React
React → Синтаксис JSX → React без JSX
Основная идея
До React 17 JSX-код трансформировался в вызовы React.createElement(), поэтому React должен был быть доступен в области видимости каждого файла, использующего JSX.
Ключевые аспекты
JSX — не валидный JavaScript — браузер не понимает синтаксис <Component />, его нужно преобразовать
Babel трансформация — <div>Hello</div> превращался в React.createElement('div', null, 'Hello')
Область видимости — без import React вызов React.createElement приводил к ошибке React is not defined
React 17+ — новый JSX Transform автоматически импортирует нужные функции из react/jsx-runtime
Плюсы нового подхода (React 17+)
Меньше boilerplate-кода
Небольшое уменьшение размера бандла
Не нужно помнить об импорте React в каждом файле с JSX
Минусы старого подхода (до React 17)
Обязательный импорт даже если React явно не используется
Линтеры ругались на "неиспользуемый импорт"
Больше кода в каждом компоненте
Частые ошибки на собеседованиях
Путают JSX с HTML — JSX это синтаксический сахар над JavaScript
Не знают про новый JSX Transform в React 17
Думают, что React нужен для работы хуков — хуки работают благодаря внутреннему механизму React, а импорт был нужен именно для JSX
Введение и проблематика
При работе с React разработчики пишут код на JSX — специальном синтаксисе, который выглядит как HTML, но на самом деле является JavaScript. Браузер не понимает JSX напрямую, поэтому код должен быть преобразован в обычный JavaScript перед выполнением.
До React 17 каждый файл с JSX требовал явного импорта React, даже если вы не использовали его напрямую в коде.
Почему это было важно?
Без понимания этого механизма разработчик мог:
Получать непонятные ошибки React is not defined
Не понимать, зачем нужен "неиспользуемый" импорт
Конфликтовать с линтерами, которые предлагали удалить импорт
Базовая теория
Что такое JSX?
JSX (JavaScript XML) — это расширение синтаксиса JavaScript, позволяющее писать разметку внутри JS-файлов:
jsx
// Это JSXconstelement= <h1className="title">Привет, мир!</h1>;
Как работала трансформация до React 17
Babel (или другой транспилятор) преобразовывал JSX в вызовы React.createElement():
❓
Code Example 1: Во что Babel преобразует JSX? Почему требовался импорт React?
jsx
// Исходный код с JSXfunctionApp() {return ( <divclassName="container"> <h1>Заголовок</h1> <p>Параграф текста</p> </div> );}
Почему требовался импорт React?
Поскольку после трансформации код содержал вызовы React.createElement(), переменная React должна была быть доступна в области видимости. Без импорта JavaScript-движок не знал, что такое React, и выбрасывал ошибку.
❓
Code Example 2: Какая ошибка возникнет в первом примере? Почему?
jsx
// ❌ До React 17 — ошибка!// ReferenceError: React is not definedfunctionButton() {return <button>Нажми меня</button>;}// ✅ До React 17 — правильноimport React from'react';functionButton() {return <button>Нажми меня</button>;}
Практические примеры
Старый подход (до React 17)
❓
Code Example 3: Зачем нужен импорт React, если мы его явно не используем в коде компонента?