Reactの「Objects are not valid as a React child」エラーを修正する

beginner⚛️ React2026-03-22| React 16以降、Next.js、Create React App — JSXをレンダリングする任意のJavaScript環境

Error Message

Objects are not valid as a React child. If you meant to render a collection of children, use an array instead.
#react#レンダリング#オブジェクト#json

エラーの内容

コンポーネントがブラウザのコンソールにこのエラーをスローします:

Objects are not valid as a React child. If you meant to render a collection of children, use an array instead.

アプリがクラッシュするか、画面が真っ白になります。スタックトレースはJSX内のどこかを指していますが、実際の原因はたいていその数行上にあります。

根本原因

Reactは文字列、数値、真偽値、配列、Reactエレメントをレンダリングする方法を知っています。しかし、プレーンなJavaScriptオブジェクトやPromiseに対しては、どう処理すればよいかわかりません。これらをJSXの子要素として渡すと、Reactはこのエラーで処理を中断します。

よくある原因:

  • {user.name} のようなフィールドではなく、オブジェクト全体 {user} をレンダリングしている
  • Date オブジェクトをレンダリングしている — new Date() は見た目がそれっぽくても文字列ではありません
  • Promiseをレンダリングしている — 非同期呼び出しへの await を忘れている
  • 実際の値にアクセスする前に、APIレスポンスをそのままJSXに渡している
  • Object.keys()Object.entries() を呼び出した後、結果に対して .map() するのを忘れている

正確な原因を特定する方法

ブラウザのコンソールでエラーメッセージ全体を確認してください。Reactは意外なほど親切にヒントを示してくれます:

Error: Objects are not valid as a React child (found: object with keys {id, name, email}).

これらのキーがヒントです。コンポーネント内でそのオブジェクトの形がJSXに流れ込んでいる箇所を検索してください。

それでもわからない場合は、returnの直前に簡単なログを追加してみましょう:

console.log(typeof someVariable, someVariable);

typeof"object" を返し、その変数が子要素として使われている場合 — それが原因です。

修正1 — オブジェクトではなくプロパティにアクセスする

十中八九、これが問題です。必要なのは一つのフィールドだけなのに、オブジェクト全体を渡しています。

// ❌ 間違い — userオブジェクト全体をレンダリングしてしまう
function UserCard({ user }) {
  return {user}
;
}

// ✅ 修正済み — 特定のプロパティをレンダリングする
function UserCard({ user }) {
  return {user.name}
;
}

修正2 — Dateオブジェクトを文字列に変換する

Date オブジェクトはレンダリングできません。表示形式に応じて .toLocaleDateString().toISOString()、または .toLocaleString() などの文字列変換メソッドを使用してください。

// ❌ 間違い
const createdAt = new Date(post.createdAt);
return {createdAt};

// ✅ 修正済み
return {createdAt.toLocaleDateString()};

修正3 — レンダリング前にPromiseをawaitする

非同期関数はPromiseを返します。await なしで呼び出すと、データではなくPromiseオブジェクトが返ってきます。

// ❌ 間違い — fetchUserはユーザーではなくPromiseを返す
function Profile() {
  const user = fetchUser();
  return {user.name}
;
}

// ✅ 修正済み — useEffect + useStateで非同期のライフサイクルを処理する
function Profile() {
  const [user, setUser] = useState(null);

  useEffect(() => {
    fetchUser().then(setUser);
  }, []);

  if (!user) return Loading...
;
  return {user.name}
;
}

修正4 — デバッグ用にJSONを文字列化する

開発中に生のAPIデータを確認したいですか?JSON.stringify() を使用してください。オブジェクトを直接渡しても動作しません。

// ❌ 間違い — オブジェクト全体をレンダリングしようとする
return ```
{data}
```;

// ✅ 修正済み — 読みやすくインデントされたJSON文字列
return ```
{JSON.stringify(data, null, 2)}
```;

本番環境にリリースする前にこれを削除してください — デバッグツールであり、UIではありません。

修正5 — コレクションを正しくmapする

Object.entries()[key, value] ペアの配列を返します。その配列は自動的にレンダリングできるわけではありません — .map() でJSXエレメントに変換する必要があります。

// ❌ 間違い — Object.entriesは配列の配列を返すだけでJSXではない
const settings = { theme: 'dark', lang: 'en' };
return {Object.entries(settings)};

// ✅ 修正済み — 各エントリをリストアイテムにする
return (
  
    {Object.entries(settings).map(([key, value]) => (
      - {key}: {value}
    ))}
  
);

修正6 — 不明な値の型をガードする

特にサードパーティAPIを使用する場合、値がどのような形で届くかを制御できないことがあります。レンダリング前に型チェックを追加しましょう。

// ❌ 間違い — responseが文字列でなくオブジェクトだとクラッシュする
return {response}
;

// ✅ 安全 — 文字列または数値の場合のみレンダリングする
return {typeof response === 'string' ? response : null}
;

確認

修正後、以下の3点を確認してください:

  • ブラウザのエラーオーバーレイが消えている
  • コンポーネントがクラッシュせずにレンダリングされる
  • テストスイートが通過する:npm test または pnpm test

エラーが続く場合、オブジェクトはコンポーネントツリーの別の場所から来ている可能性があります。エラーメッセージに表示されているキーを追っていけば、そこにたどり着けます。

予防のヒント

TypeScriptはこれをコンパイル時に検出します。 プロパティを string として型定義すれば、TypeScriptが誤って User オブジェクトを渡すことを防いでくれます。これにより、ブラウザで問題が発生する前に、このクラスのバグ全体を排除できます。

interface Props {
  name: string; // 呼び出し元は文字列を渡す必要があり、オブジェクトは不可
}

function Label({ name }: Props) {
  return {name};
}

APIレスポンスは境界でデストラクチャリングしましょう。 データがアプリに入ってくる箇所で、実際に必要なフィールドだけを取り出してください — コンポーネントに広がる前に。深くネストされた未知のJSONは、レスポンスを JSON Formatter & Validator に貼り付けて構造を可視化し、どのキーを対象にすべきか確認するとよいでしょう。すべてブラウザ上で動作し、データがアップロードされることはありません。

TypeScriptを使用していない場合は、PropTypesで軽量なランタイムバリデーションを使用しましょう:

import PropTypes from 'prop-types';

UserCard.propTypes = {
  user: PropTypes.shape({
    name: PropTypes.string.isRequired,
  }).isRequired,
};

Related Error Notes