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)は、JavaScriptでHTMLのようなコードを書くための構文拡張です。ブラウザは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のバージョンを更新する
最後に、以下のコマンドでreactとreact-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のバージョンによって、このエラーの解決方法が異なることを覚えておいてください。
このエラーに遭遇した経験はありますか?(もしそうであれば)どのように解決しましたか?以下のコメント欄でぜひお聞かせください。