カテゴリ: React 更新日: 2026/02/22

ReactのPropsとStateでよくあるエラーと解決方法まとめ!初心者向け解説

PropsとStateでよくあるエラーと解決方法まとめ
PropsとStateでよくあるエラーと解決方法まとめ

先生と生徒の会話形式で理解しよう

生徒

「Reactでプログラムを書いていると、PropsやStateに関するエラーがよく出て困ります。どうすればいいですか?」

先生

「Props(プロップス)やState(ステート)はReactの基本ですが、エラーになりやすいポイントがあります。よくある間違いを理解しておけば安心ですよ。」

生徒

「どんなエラーが多いんですか?そして、どう直せばいいんですか?」

先生

「それでは、実際にPropsやStateでよくあるエラーとその解決方法を、具体例と一緒に説明していきましょう!」

1. Propsを直接変更しようとしてエラーになる

1. Propsを直接変更しようとしてエラーになる
1. Propsを直接変更しようとしてエラーになる

Reactでは、Propsは「親コンポーネントから子コンポーネントに渡されるデータ」であり、基本的に読み取り専用の値として扱います。いちど親から渡されたPropsは、子コンポーネント側で書き換えてはいけません。書き換えようとすると、エラーになったり、画面に予想と違う結果が表示されたりします。

イメージとしては、Propsは「親から渡された手紙の内容」のようなものです。ポストから受け取った手紙を勝手に書き換えてしまうと、本来のメッセージが分からなくなってしまいますよね。Reactでも同じで、「内容を変えたいときは親にお願いして、新しい手紙を書き直してもらう」というルールになっています。


function Child(props) {
  // ❌ NG: propsの値を直接変更してはいけない
  props.message = "変更しました"; 
  return <h1>{props.message}</h1>;
}
(このコードはPropsを書き換えているため、思った通りに動作せず、エラーになったり画面に正しく表示されなかったりします)

Reactの基本的な考え方として、「どの値を表示するか」は親コンポーネントが決めて、子コンポーネントはそれをそのまま受け取って表示するだけ、という役割分担があります。子どもは表示担当、親が値を管理する担当、と覚えておくと分かりやすいです。

そのため、値を変えたいときは、親コンポーネント側でState(ステート)を更新し、その更新された値をPropsとして子コンポーネントに渡すのが正しい流れになります。下のサンプルでは、ボタンをクリックすると親のStateが変わり、その結果として子の表示が変わる様子を確認できます。


import React, { useState } from "react";

function Child(props) {
  return <h1>{props.message}</h1>;
}

function App() {
  const [message, setMessage] = useState("こんにちは!");

  return (
    <div>
      <Child message={message} />
      <button onClick={() => setMessage("変更されました!")}>
        メッセージを変更
      </button>
    </div>
  );
}

export default App;
(画面に最初は「こんにちは!」と表示され、ボタンをクリックすると親コンポーネントのStateが更新されて「変更されました!」に変わります)

このように、「Propsは読むだけ」「値を変えるのは親コンポーネントのState経由」というルールを意識しておくと、ReactのPropsエラーを避けやすくなります。プログラミングが初めての方は、親子の会話のように「親が内容を決めて、子はそれを素直に伝えるだけ」とイメージしながらコードを読むと理解しやすくなります。

2. Stateを直接書き換えてしまうエラー

2. Stateを直接書き換えてしまうエラー
2. Stateを直接書き換えてしまうエラー

StateはReactで「今の状態」を管理するための大切な仕組みです。しかし、このStateに直接代入してしまうと、Reactが変更を認識できず、画面が更新されないという問題が起こります。たとえば、count = count + 1 のように書いてしまうと、一見正しく動きそうに見えても、実際にはReactが変化を追跡できません。

イメージとしては、冷蔵庫に新しい食材を入れたのに、家族が見るレシピノートにその情報を書かないようなものです。冷蔵庫の中は変わっているのに、レシピノートが古いままなので、家族は変化に気づけません。Reactもこれと同じで、「変わったよ」と知らせる専用の方法、つまりsetCountのような更新関数を使う必要があります。


import React, { useState } from "react";

function App() {
  const [count, setCount] = useState(0);

  // ❌ NG: 直接代入するとReactは気づかない
  const wrongUpdate = () => {
    count = count + 1;
  };

  // ✅ OK: setCountを使って更新する
  const correctUpdate = () => {
    setCount(count + 1);
  };

  return (
    <div>
      <p>現在のカウント: {count}</p>
      <button onClick={wrongUpdate}>間違った更新</button>
      <button onClick={correctUpdate}>正しい更新</button>
    </div>
  );
}

export default App;
(正しい方法であるsetCountを使うと、ボタンを押した瞬間にカウントが増えますが、間違った方法では画面の表示は変わりません)

State更新関数を使うことは、Reactが画面を正しく再描画するための非常に重要なポイントです。特に初心者の方は、「Stateは直接触らず、必ずsetState系の関数を使う」というルールを最初に覚えておくと、エラーを大きく減らせます。Reactがどのように状態を管理しているかを理解するきっかけにもなるので、基本としてしっかり身につけておくと安心です。

3. PropsやStateの初期値がundefinedになる

3. PropsやStateの初期値がundefinedになる
3. PropsやStateの初期値がundefinedになる

初心者によくあるエラーが「Cannot read property '〇〇' of undefined」というものです。これは、PropsやStateの初期値を正しく設定していないときに起こります。

たとえば、配列やオブジェクトを使う場合は、最初に空の配列[]や空のオブジェクト{}を指定しておくと安全です。


import React, { useState } from "react";

function App() {
  // ❌ NG: 初期値がundefined
  // const [user, setUser] = useState();

  // ✅ OK: 初期値を空のオブジェクトにする
  const [user, setUser] = useState({ name: "", age: 0 });

  return (
    <div>
      <p>名前: {user.name}</p>
      <p>年齢: {user.age}</p>
    </div>
  );
}

export default App;
(初期値を設定しているので、エラーが出ずに「名前:」「年齢:0」と表示されます)

4. PropsやStateの非同期更新で値がずれる

4. PropsやStateの非同期更新で値がずれる
4. PropsやStateの非同期更新で値がずれる

Stateの更新は非同期で行われることが多いため、すぐに新しい値を使おうとするとずれてしまうことがあります。解決方法は、更新関数に「前の値」を渡して計算する方法です。


import React, { useState } from "react";

function App() {
  const [count, setCount] = useState(0);

  // ❌ NG: 古い値を参照してしまうことがある
  const wrongIncrement = () => {
    setCount(count + 1);
    setCount(count + 1);
  };

  // ✅ OK: 関数型の更新を使う
  const correctIncrement = () => {
    setCount((prev) => prev + 1);
    setCount((prev) => prev + 1);
  };

  return (
    <div>
      <p>現在のカウント: {count}</p>
      <button onClick={wrongIncrement}>間違った加算</button>
      <button onClick={correctIncrement}>正しい加算</button>
    </div>
  );
}

export default App;
(「間違った加算」では1しか増えませんが、「正しい加算」では2増えます)

5. Propsの型が合わないときのエラー

5. Propsの型が合わないときのエラー
5. Propsの型が合わないときのエラー

親コンポーネントから渡すPropsの型(文字列・数値など)が違うと、意図しない表示やエラーが発生することがあります。例えば、数値を文字列として扱ってしまうなどです。

解決策は、渡す値の型を確認することや、PropTypesやTypeScriptを使って型を明示することです。


import React from "react";
import PropTypes from "prop-types";

function Child(props) {
  return <h1>年齢: {props.age}</h1>;
}

Child.propTypes = {
  age: PropTypes.number.isRequired,
};

export default Child;
(ageを文字列で渡すとエラーが表示され、間違いに気づけます)

まとめ

まとめ
まとめ

この記事では、ReactのPropsとStateでよく起こるエラーとその解決方法を初心者向けに解説しました。Propsは親から子に渡される読み取り専用のデータであり、直接変更するとエラーになります。一方、Stateはコンポーネントが管理するデータで、必ず更新関数(set関数)を通じて変更しなければ、Reactが変化を検知できず画面が更新されません。また、StateやPropsの初期値が未設定だとundefinedによるエラーが発生したり、非同期更新のタイミングで値がずれることもあります。これらの問題は、初期値の設定や関数型の更新、型のチェックを行うことで解決できます。

さらに、PropsとStateを組み合わせることで、ログイン状態の切り替えやフォーム入力のリアルタイム反映など、より実用的でインタラクティブなReactアプリを作ることができます。Propsはデータや関数を子コンポーネントに渡す役割、Stateはそのコンポーネント内部でデータを管理し変化を反映させる役割を持つことを理解すれば、エラーを防ぎつつ効率的に開発できます。

初心者の方は、Propsは「親からもらうプレゼント」、Stateは「自分のノート」と考え、Stateは必ず更新関数を使って変更する、Propsは読み取り専用で変更しない、初期値を設定する、非同期更新では前の値を参照する、といったルールを押さえておくと、Reactでのデータ管理がスムーズに行えます。PropTypesやTypeScriptで型を明示することも、予期せぬエラーを防ぐ重要なポイントです。

サンプルプログラムで復習

import React, { useState } from "react";
import PropTypes from "prop-types";

function Child({ age }) {
  return <h1>年齢: {age}</h1>;
}

Child.propTypes = {
  age: PropTypes.number.isRequired,
};

function App() {
  const [count, setCount] = useState(0);
  const [isLogin, setIsLogin] = useState(false);

  const increment = () => {
    setCount((prev) => prev + 1);
  };

  return (
    <div>
      {isLogin ? <Child age={count} /> : <p>ログインしてください</p>}
      <button onClick={() => setIsLogin(!isLogin)}>
        {isLogin ? "ログアウト" : "ログイン"}
      </button>
      <button onClick={increment}>カウントを増やす</button>
    </div>
  );
}

export default App;
(ログイン状態に応じてChildコンポーネントの表示が切り替わり、カウントボタンを押すとStateが正しく更新されます。PropsとStateの使い方とエラー回避を同時に確認できます)
先生と生徒の振り返り会話

生徒

「Propsは読み取り専用、Stateは更新関数で管理するもの、という基本ルールが理解できました。」

先生

「その通りです。これを守ることで、Reactのコンポーネントが正しく画面を更新し、エラーも防げます。」

生徒

「初期値を設定したり、非同期更新では前の値を参照する方法も覚えました。」

先生

「はい。PropsとStateの違いを意識しながら、安全に更新することがReact開発の基本です。型チェックも活用すると、さらに安心ですね。」

生徒

「これで、よくあるPropsやStateのエラーを防ぎつつ、実用的なアプリを作れる気がします!」

先生

「その意気です。まずは小さなアプリで復習し、PropsとStateの使い方に慣れていきましょう。」

この記事を読んだ人からの質問

この記事を読んだ人からの質問
この記事を読んだ人からの質問

プログラミング初心者からのよくある疑問/質問を解決します

ReactのPropsを直接変更するとエラーになるのはなぜですか?

ReactのPropsは「親コンポーネントから渡される読み取り専用のデータ」であり、子コンポーネントで書き換えるとReactの仕組みと合わずエラーが発生します。Propsを変更したい場合は、必ず親コンポーネントでStateを更新して、新しい値をPropsとして渡す必要があります。
カテゴリの一覧へ
新着記事
New1
React
Reactコンポーネントの再利用と分割を完全マスター!初心者でもわかるコンポーネント設計
New2
React
ReactでAxiosインターセプターの使い方を完全ガイド!初心者でもわかるリクエストとレスポンスの処理方法
New3
React
JSXの書き方!初心者でもわかるReactタグと属性の基本ルール解説
New4
React
ReactとDockerを使った開発環境構築の基本を徹底解説!初心者でもわかるReactとDockerの連携方法
人気記事
No.1
Java&Spring記事人気No1
React
ReactでonChangeイベントを使ってフォーム入力値を管理する方法を初心者向けに解説
No.2
Java&Spring記事人気No2
React
ReactとTypeScriptの環境構築をやさしく解説!Viteとtsconfigの設定も丁寧に紹介
No.3
Java&Spring記事人気No3
React
Reactのイベントハンドリングのアンチパターンまとめ!初心者でもわかる注意点
No.4
Java&Spring記事人気No4
React
Reactのカスタムフックの作り方を完全ガイド!再利用可能なロジックを切り出す仕組み
No.5
Java&Spring記事人気No5
React
ReactでFetch APIのローディング状態を管理する方法|初心者にもわかる解説
No.6
Java&Spring記事人気No6
React
ReactのuseStateとuseEffectでよくあるエラーと解決方法ガイド!初心者でもわかるReactフック
No.7
Java&Spring記事人気No7
React
create-react-appでReactプロジェクトを作成する手順を初心者向けに完全解説!
No.8
Java&Spring記事人気No8
React
Reactでファイルアップロードを実装する方法を解説!Fetch APIで画像やPDFを送る仕組みを初心者向けに紹介