なぜこのエラーが発生するのか
Reactは画面に表示するものに対して非常に厳格です。JSX要素、文字列、数値、配列といった特定のデータ型を期待しています。このエラーが表示される場合、表示したい最終結果ではなく、誤って関数の定義そのものをReactに渡してしまっていることを意味します。
関数を「レシピ」、JSX要素を「料理」と考えてみてください。Reactは料理の出し方は知っていますが、レシピそのものを「レンダリング(表示)」する方法は知りません。このミスは、バニラ JavaScriptからReactに移行した開発者が遭遇する一般的なバグの約15〜20%を占めています。
このエラーが紛れ込む4つのパターン
1. ブラケットの付け忘れ
これが最も頻繁な原因です。完璧なコンポーネントを定義したのに、波括弧の中で名前だけでレンダリングしようとした場合に起こります。JSXのブラケット(< >)がないと、Reactは要素ではなく、生の関数ポインタとして認識してしまいます。
// ❌ 誤り: 関数自体を渡してしまっている
const MyComponent = () => <div>Hello World</div>;
function App() {
return (
<div>
{MyComponent}
</div>
);
}
修正方法: コンポーネント名を < /> タグで囲みます。これにより、Reactにコンポーネントをインスタンス化し、その出力をレンダリングするように指示できます。
// ✅ 正解: Reactが要素をレンダリングするようになる
function App() {
return (
<div>
<MyComponent />
</div>
);
}
2. 括弧の呼び出し忘れ
ヘルパー関数はJSXをクリーンに保つのに役立ちます。しかし、括弧を付けずに関数名だけを参照すると、コードは実行されません。単にその関数を指し示しているだけになります。
// ❌ 誤り
function Dashboard() {
const renderHeader = () => <h1>Welcome Back</h1>;
return (
<div>
{renderHeader}
</div>
);
}
修正方法: 常に () を付けて関数を呼び出し、内部のJSXを返すようにします。
// ✅ 正解
return (
<div>
{renderHeader()}
</div>
);
3. プロップスの命名規則の罠
コンポーネントをプロップスとして渡す際、Reactの命名規則が重要になります。プロップス名が小文字で始まっていると、Reactはそれをカスタムコンポーネントではなく、標準的なHTMLタグ(<div>など)として扱います。
// ❌ 誤り: 'content' は通常の変数として扱われる
const Layout = ({ content }) => {
return <div>{content}</div>;
};
<Layout content={MyProfilePage} />
修正方法: プロップス名の先頭を大文字にします。この単純な変更により、Reactはその値をレンダリング可能なコンポーネントとして扱う必要があると判断します。
// ✅ 正解: 'Content' がコンポーネントとして認識される
const Layout = ({ Content }) => {
return (
<div>
<Content />
</div>
);
};
<Layout Content={MyProfilePage} />
4. 関数を返してしまうロジック
複雑な条件分岐や高階関数を使用していると、誤って関数を返してしまうことがあります。これは、三項演算子の中でアロー関数を不適切に使用した場合によく起こります。
// ❌ 誤り: trueのブランチがJSXではなく関数を返している
const status = (isAdmin) => {
return isAdmin ? () => <span>Admin</span> : <span>User</span>;
};
この場合、isAdmin がtrueだと、Reactは () => <span>...</span> を受け取ります。Reactはこのロジックブロックをどう扱えばいいか判断できません。
プロのようにデバッグする方法
エラーの原因がすぐに見つからなくても、焦る必要はありません。以下の3つのステップで原因を特定しましょう。
- スタックトレースを精査する: ブラウザのコンソールには通常、レンダリングに失敗した正確な行が表示されます。まずはそこから確認しましょう。
- typeofテスト: 疑わしい変数を
console.log(typeof variable)で囲んでみてください。コンソールに "function" と表示されたら、それがバグの原因です。 - React DevTools: コンポーネントツリーを確認します。名前ではなく関数のシグネチャのように見えるノードがあれば、それが犯人です。
重要なポイント
- JSXは糖衣構文: すべての
<MyComponent />は、実際にはReact.createElement(MyComponent)です。{MyComponent}と渡すのは、UIの真ん中に関数の参照を放り込んでいるだけです。 - 命名規則(ケース)が重要: コンポーネント名は必ず大文字で始めてください。Reactはこれによって、組み込みのHTMLタグとカスタムロジックを区別しています。
- 要素 vs 設計図: 関数は単なる設計図です。Reactが画面に何かを表示するには、完成した家(要素)が必要です。

