PassFront
  1. PassFront
  2. База знаний
  3. Основы React

Зачем нужно всегда импортировать React в scope модуля?

Основы React

Это правило из «старого мира»: до React 17 любой файл с JSX обязан был иметь import React from 'react' — иначе скомпилированный код падал. Сегодня правило устарело.

Причина исторического правила

JSX — не JavaScript; компилятор (Babel/TS) превращал его в вызовы React.createElement:

const badge = <span className="badge">7</span>;
// ↓ компиляция (старый трансформ)
const badge = React.createElement('span', { className: 'badge' }, '7');

В скомпилированном коде появляется идентификатор React. Если его нет в области видимости модуля — ReferenceError: React is not defined в рантайме, хотя в исходнике «React вроде не используется». Отсюда требование импортировать React в scope каждого JSX-модуля (и ESLint-правило react/react-in-jsx-scope).

Что изменилось (React 17+, 2020)

Новый JSX-трансформ: компилятор сам импортирует служебную функцию из jsx-runtime:

import { jsx as _jsx } from 'react/jsx-runtime'; // вставляется автоматически
const badge = _jsx('span', { className: 'badge', children: '7' });

Ручной импорт для JSX стал не нужен; правило react/react-in-jsx-scope в конфигурациях отключают. Требуется настройка компилятора: "jsx": "react-jsx" в tsconfig или соответствующий пресет Babel — в современных шаблонах (Vite, Next.js) это по умолчанию.

Когда импорт всё же нужен

Только для явного использования API: import { useState, memo } from 'react', классовые компоненты, типы (React.ReactNode). Сам по себе JSX импорта больше не требует.

Коротко для собеседования

Раньше JSX компилировался в React.createElement — идентификатор React должен был быть в scope каждого JSX-файла, иначе ReferenceError. С React 17 новый трансформ автоматически импортирует jsx-runtime, и import React нужен только для явного API (хуки, классы, типы).

Другие вопросы раздела