← Назад к вопросам

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

2.0 Middle🔥 221 комментариев
#React

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

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

Это классический вопрос, который был актуален для React версий до 17. Чтобы понять причину, нужно разобраться с тем, как JSX трансформируется в JavaScript.

Как работает JSX трансформация

До React 17

Когда Babel обрабатывает JSX, он трансформирует его в вызовы функции React.createElement():

// Исходный JSX
const element = <div className="greeting">Hello!</div>;

// Трансформируется в:
const element = React.createElement(
  "div",
  { className: "greeting" },
  "Hello!"
);

Как видишь, JSX превращается в React.createElement(). Если React не импортирован, то React.createElement не определена, и код выбросит ошибку:

// ОШИБКА! React не импортирован
const element = <div>Hello</div>;
// ReferenceError: React is not defined

Поэтому старые версии требовали:

import React from "react";

const element = <div>Hello</div>; // Теперь работает

Пример ошибки

// ❌ Без импорта React
// (только с JSX, без прямого использования React)

function MyComponent() {
  return <h1>Hello World</h1>;
}

// Этот код не компилируется:
// ReferenceError: React is not defined
// ✅ С импортом React

import React from "react";

function MyComponent() {
  return <h1>Hello World</h1>;
}

React 17+ и новый JSX Transform

Начиная с React 17, Facebook представила новый JSX Transform, который избавил разработчиков от необходимости импортировать React в каждом файле с JSX.

Как это работает

Теперь Babel использует новый импорт вместо React.createElement():

// Новый трансформер (React 17+)
// Исходный JSX
const element = <div>Hello</div>;

// Трансформируется в:
import { jsx as _jsx } from "react/jsx-runtime";
const element = _jsx("div", null, null, "Hello");

Импорт из react/jsx-runtime происходит автоматически, поэтому разработчик больше не должен явно импортировать React:

// ✅ Современный подход (React 17+)
// React импортировать НЕ нужно!

function MyComponent() {
  return <h1>Hello World</h1>;
}

// Это работает отлично

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

Хотя JSX трансформация автоматична в React 17+, есть случаи, когда нужно явно импортировать React:

1. Использование React API напрямую

// Нужен импорт, потому что используем React напрямую
import React, { useState, useEffect } from "react";

function MyComponent() {
  const [count, setCount] = useState(0);
  
  useEffect(() => {
    console.log("Component mounted");
  }, []);
  
  return <div>{count}</div>;
}

2. Использование React.memo, React.lazy и других утилит

import React from "react";

const HeavyComponent = React.lazy(() => import("./Heavy"));

const MemoizedComponent = React.memo(({ value }) => {
  return <div>{value}</div>;
});

3. Работа с контекстом

import React, { createContext, useContext } from "react";

const ThemeContext = createContext();

4. Использование React.Fragment

import React from "react";

// Два эквивалентных способа:
function MyComponent() {
  return (
    <React.Fragment>
      <div>Item 1</div>
      <div>Item 2</div>
    </React.Fragment>
  );
  
  // Или сокращённо (без импорта React):
  // return <>
  //   <div>Item 1</div>
  //   <div>Item 2</div>
  // </>;
}

Историческая причина

Этот вопрос часто задают на собеседованиях, потому что раньше это была обязательным требованием. Разработчики привыкли видеть:

// Классический импорт времён React 16 и ранее
import React from "react";
import ReactDOM from "react-dom";

Но сейчас требование ослаблено, хотя некоторые проекты могут использовать старый JSX Transform.

Как проверить конфигурацию проекта

В tsconfig.json или babel.config.js можно найти, какой трансформер используется:

// tsconfig.json
{
  "compilerOptions": {
    "jsx": "react-jsx" // Новый трансформер (React 17+)
    // или
    // "jsx": "react" // Старый (требует импорта React)
  }
}

Современный подход (React 17+)

// ✅ Современный способ — React импортировать не нужно
import { useState } from "react";

function Counter() {
  const [count, setCount] = useState(0);
  
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

Резюме

  • React 16 и ранее: нужно импортировать React в каждом файле с JSX
  • React 17+: импорт автоматический благодаря новому JSX Transform
  • Всегда импортируй: хуки (useState, useEffect), контекст, React.memo, React.lazy и другие API
  • Импортировать не нужно: просто для использования JSX в современных проектах

Этот вопрос показывает понимание того, как Babel трансформирует JSX в JavaScript и как эволюционировал React.