Reactを使った作業は時に複雑ですが、理解し難いエラーに遭遇した時にはなおのこと。

Reactで見られる一般的なエラーの中に、「’React’ must be in scope when using JSX」(JSXの使用時にはReactがスコープ内になければなりません)というものがあります。このメッセージは、JSXを使用するコンポーネントで、Reactが適切にインポートまたは初期化されていない場合に発生します。

今回はこのエラーを取り上げ、原因と解決策を見ていきます。

「’React’ must be in scope when using JSX」エラーの原因

JSX(JavaScript XML)は、JavaScriptHTMLのようなコードを書くための構文拡張です。ブラウザはJSXを理解しませんが、Create React Appのようなツールキットには、JSXコードを有効なJavaScriptコードに変換する機能があり、これによって、ブラウザに理解させることが可能です。

バージョン17.0以前のReactでは、JSXは変換ツールによってコンパイル時にReact.createElement()関数呼び出しに変換されます。このため、React要素を動作させるにはReactのインポートが必要です。React v17.0からは、JSX Transformが導入されており、Reactパッケージの新たなエントリポイントから専用の関数が自動でインポートされ、JSXを明示的に使用するすべてのファイルでReactをインポートする必要がなくなります。

以下、関数コンポーネントの例を見てみましょう。

function App() {
  return <h1>Welcome to Kinsta!</h1>;
}

コンパイル時に通常のJavaScriptに変換されます。

function App() {
  return React.createElement('h1', null, 'Welcome to Kinsta!');
}

Reactが未定義であることから、JSX使用時には常に「’React’ must be in scope when using JSX」エラーが投げられます。

「’React’ must be in scope when using JSX」エラーを解決する方法1(2通り)

解決方法は、使用しているバージョンによって異なります。

  • React v17以前
  • React v17以降

1. Import宣言をインクルードまたは修正する(React v17以前)

古いバージョンのReactを使用している場合、’react’のImport宣言がない、または宣言に誤りがある可能性があります。ファイルの先頭に正しいimport宣言があることを確認してください(Reactの「R」は大文字)。

// 誤り ❌
import react  from 'react';

// 正解 ✅
import React  from 'react';

関数コンポーネントは、通常のJavaScriptに変換すると、以下のようになります。

import React  from 'react';

function App() {
  return React.createElement('h1', null, 'Kinstaへようこそ!');
}

2. ESLintの設定を更新する(React v17以降)

React v17.0には、JSX Transformが導入されています。これは、Reactパッケージの新たなエントリポイントから、特別な関数を自動的にインポートする機能であり、JSXを明示的に使用するすべてのファイルでReactをインポートせずに済みます。

例を見てみましょう。例えば、次のような関数コンポーネントがあるとします。

function App() {
  return <h1>Kinstaへようこそ!</h1>;
}

JSX Transformでコンパイルすると以下のようになります。

// コンパイラによって挿入(自分でインポートする必要なし)
import {jsx as _jsx} from 'react/jsx-runtime';

function App() {
  return _jsx('h1', { children: 'Kinstaへようこそ!' });
}

このように、JSXを使用するためにReactをコンポーネントにインポートする必要がありません。package.jsonファイルをチェックし、Reactのバージョンを確認してもこのエラーが消えない場合は、ESLintの設定を更新してください。

この時点で、厳密にはReactエラーではなく、ESLintエラーということになります。

)ReactプロジェクトでESLintのようなリントツールを頻繁に使用する目的は、コードをチェックし、現在または将来的にコードを壊す可能性のある潜在的なエラーを検出することにあります。ファイルでJSXを検出すると、Reactを強制的にインポートします。

お使いのバージョンがv17.0以上であることを確認した上で、ReactでJSXを使用する際にReactをインポートするルールを無効にしてください。

ESLintの設定を更新する方法は大きく分けて2つあります。.eslintrc.jsまたは.eslintrc.jsonファイルがある場合、.eslintrc.jsファイルに以下のルールを追加します。

"rules": {
  // ...
  "react/react-in-jsx-scope": "off",
  "react/jsx-uses-react": "off",
 }

どちらのファイルもない場合は、package.jsonファイルのeslintConfigオブジェクトを更新します。

{
  "name": "quotes-circle",
  // ...
  "dependencies": {
    // ...
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ],
    "rules": {
      "react/jsx-uses-react": "off",
      "react/react-in-jsx-scope": "off"
    }
  },
}

上記では、react-in-jsx-scopeルールが無効になっているため、Reactのインポートに失敗してもESLintがエラーを投げることはありません。

これで「’React’ must be in scope when using JSX」エラーが解消されますが、何か他の原因によってエラーが消えない場合もあります。

まだエラーが表示されている場合は、次のセクションに進みましょう。

「’React’ must be in scope when using JSX」エラーを解決する方法2(3通り)

エラーがまだ解消されない場合は、以下3つの解決策を実行してみてください。

1. Reactスクリプトのバージョンを更新する

ターミナルで次のコマンドを実行し、reactスクリプトのバージョンを更新します。

// npm
npm install react-scripts@latest

// yarn
yarn add react-scripts@latest

2. Node_modulesフォルダとpackage-lock.jsonファイルを削除する

依存関係の一部が誤ってインストールされてしまっている可能性もあるため、node_modulesフォルダとpackage-lock.jsonファイル(package.jsonではない)を削除します。修正後、以下のコマンドを実行して、パッケージを新たにインストールしてください。

npm install

インストールしたら、開発サーバーを再起動します。

3. ReactとReact-Domのバージョンを更新する

最後に、以下のコマンドでreactreact-domのバージョンを更新するのも有効です。

// npm
npm install react@latest react-dom@latest

// TypeScriptを使用している場合
npm install --save-dev @types/react@latest @types/react-dom@latest

// もしくは

// yarn
yarn add react@latest react-dom@latest

// TypeScriptを使用している場合
yarn add @types/react@latest @types/react-dom@latest --dev

これで確実にエラーが消えるはずです。

まとめ

「’React’ must be in scope when using JSX」は、Reactを使用する開発者であれば、十分に遭遇する可能性のあるエラーです。React v17以前のバージョンでは、ファイル内でJSXが使用されているにもかかわらず、Reactライブラリが適切にインポート、またはインクルードされていない場合に発生します。React v17の上位バージョンでは、ESLintの設定がエラーを返す場合、node_modulesフォルダ内の依存関係が間違ってインストールされている場合に発生するのが一般的です。

Reactのバージョンによって、このエラーの解決方法が異なることを覚えておいてください。

このエラーに遭遇した経験はありますか?(もしそうであれば)どのように解決しましたか?以下のコメント欄でぜひお聞かせください。