Reactを学び始めた初心者の方が、最初につまずきやすいポイントが「Props(プロップス)」と「State(ステート)」の違いや使い分けです1。
Reactのユーザーインターフェース(UI)は、「データの変化に応じて自動的に画面が書き換わる」という便利な仕組みを持っています3。この画面の表示を決定するデータこそが、PropsとStateなのです4。
この記事では、PropsとStateの基本的な概念から、具体的なReactのコード例、そして実践的な使い分けの基準まで、初心者の方に向けてわかりやすく解説します。
1. Reactの基本:PropsとStateは「データの持ち方」が違う

Reactのコンポーネントは、データを入力として受け取り、画面に表示するHTML(JSX)を出力する「関数」のようなものです3。この入力データを扱う仕組みとして、PropsとStateという2つのオブジェクトが用意されています1。
この2つの違いを、プログラミングや日常の言葉で例えると次のようになります。
- Props(プロパティ): コンポーネントの外部(親)から渡される「引数(パラメータ)」や「設定指示書」です1。コンポーネント自身では内容を書き換えることができません1。
- State(ステート): コンポーネントが内部に持っている「ローカル変数」や「自身の記憶」です1。ユーザーの操作などによって、自分自身で自由に書き換えることができます1。
この「誰がデータを管理し、誰が変更できるのか」という違いを意識することが、Reactをマスターするための第一歩になります。
2. Props(プロップス)とは?「親から子へと渡す読み取り専用データ」
Propsは、親コンポーネントから子コンポーネントへと一方通行で受け渡されるデータのことです1。Reactではデータが常に上(親)から下(子)へと流れる「一方向データフロー」という厳格なルールがあります4。
Propsは「読み取り専用(変更不可)」
Propsの最も重要なルールは、「受け取った子コンポーネント側で直接書き換えてはいけない」ということです1。これは、同じ入力に対しては常に同じ画面を出力するという、関数型プログラミングの「純粋関数」の考え方に基づいています3。
もし子コンポーネントが勝手にPropsを書き換えてしまうと、データの出所がわからなくなり、アプリが予期せぬ挙動を起こす原因になります。データを変更したい場合は、必ず親コンポーネント側でデータを更新し、新しいPropsとして再配達してもらう必要があります9。
具体的なコード例で見るPropsの使い方
Propsは、コンポーネントの見た目や表示内容を外側からカスタマイズする「設定値」として使います3。
例えば、ユーザーのアバター画像を表示するコンポーネントを作ってみましょう。JavaScriptの「分割代入(Destructuring)」を使うと、Propsをすっきりと受け取ることができます8。
JavaScript
// 子コンポーネント:アバター画像を表示します
function Avatar({ person, size = 100 }) {
// personとsizeがPropsとして渡されてきます
return (
<img
className=”avatar”
src={getImageUrl(person)}
alt={person.name}
width={size}
height={size}
/>
);
}
// 親コンポーネント:子コンポーネントを呼び出してデータを渡します
export default function Profile() {
return (
<Avatar
person={{ name: ‘サマーズ・ハシ’, imageId: ‘YfeOqp2’ }}
size={100}
/>
);
}
このコード例では、Avatarコンポーネントは親であるProfileからpersonというオブジェクトと、sizeという数値を受け取り、それに基づいて画像をレンダリングしています8。sizeにはデフォルト値(100)が指定されているため、親から指定がない場合でも安全に動作します8。
便利なPropsの受け渡しテクニック
- スプレッド構文(…)での一括伝達: 親から受け取ったPropsをそのままさらに奥の子コンポーネントへ渡したい場合、{…props}と書くことでまとめて転送できます8。ただし、多用しすぎるとコードの追いかけが難しくなるため、注意しましょう8。
- 特別な「children」プロップ: コンポーネントのタグで囲んだ中身は、自動的にchildrenという特別な名前のPropとして子コンポーネントに渡されます8。これを使うと、デザインの「枠組み(カード型など)」を共通化して中身を自由に差し替えるといった、柔軟なレイアウト構築が可能になります13。
JavaScript
function Card({ children }) {
return <div className=”card-container”>{children}</div>;
} - イベントハンドラ(関数)の受け渡し: データは上から下にしか流せませんが、「ボタンが押された」などのイベントを子から親に伝えたいことがあります15。その場合は、親から子へ「関数」をPropsとして渡しておき、子の内部でその関数を実行します9。
3. State(ステート)とは?「コンポーネントが自律的に管理する動的な記憶」
Stateは、コンポーネントの内部で保持されるデータであり、時間やユーザーの操作(クリックや文字入力など)によって変化するデータを指します1。
なぜ普通の変数ではなくStateが必要なのか?
JavaScriptの通常の変数を書き換えても、Reactは「画面を更新しなさい」という命令を検知できません17。Stateとしてデータを管理することで、Reactはその値の変化を即座にキャッチし、自動的に関係するコンポーネントを再レンダリング(再描画)してくれます1。
useStateフックを使った具体的なコード例
モダンなReact(関数コンポーネント)では、useStateという「フック(Hook)」を使ってStateを宣言します17。
JavaScript
import React, { useState } from ‘react’;
function Counter() {
// countというState変数と、それを更新するためのsetCount関数を用意します。初期値は0です。
const [count, setCount] = useState(0);
function handleClick() {
// ボタンがクリックされたら、現在のカウントに1を足してStateを更新します
setCount(count + 1);
}
return (
<button onClick={handleClick}>
クリックされた回数: {count} 回
</button>
);
}
ボタンをクリックしてsetCountが実行されると、Reactは新しいcountの値を使って、このコンポーネントをもう一度実行(再レンダリング)し、画面の数字を書き換えます19。
Stateを使う際の注意点:非同期とバッチ処理
Stateの動作には、いくつか特有のルールがあります。
- 更新は「非同期」で行われます: setCountを呼び出した直後に、次の行でconsole.log(count)を実行しても、表示される値はまだ古いままです1。Stateの変更は、次のレンダリング時に反映されるようにスケジュールされるためです19。
- まとめて処理されます(バッチ処理): Reactはパフォーマンスを守るため、1つのイベントの中で複数回Stateが変更されても、可能な限りそれらをまとめて1回の再レンダリングで済ませようとします7。
- 前の値に基づいて更新する場合: 直前のStateの値を確実に使いたい場合は、setCount(count + 1)ではなく、setCount(prev => prev + 1)のように「更新用の関数」を渡す記述方法が推奨されます19。
オブジェクトや配列のStateは「不変性(イミュータビリティ)」を守る
Stateにオブジェクトや配列を使う場合、既存のデータを直接書き換えてはいけません18。Reactは「データの参照先(メモリ上の住所)」が変わったかどうかで値の変化を判断するためです18。
以下のように、常にスプレッド構文などを使って「新しいオブジェクトや配列のコピー」を作成して更新してください23。
JavaScript
const [position, setPosition] = useState({ x: 0, y: 0 });
// ❌ 間違った方法(直接書き換えは検知されません)
// position.x = 100;
// setPosition(position);
// ⭕ 正しい方法(新しいオブジェクトを作って渡します)
setPosition(prev => ({
…prev,
x: 100
}));
配列の場合も、pushやpopなどの元の配列を壊すメソッドは避け、filterやmap、スプレッド構文([…prev, ‘新しい要素’])のような非破壊的なメソッドを使いましょう17。
4. PropsとStateの比較:使い分けの判断基準
PropsとStateは、どちらもコンポーネントの表示内容を変化させるものですが、明確な違いがあります。初心者の方は、以下の比較表を参考に使い分けてみてください。
一目でわかるPropsとStateの比較表
| 特徴・性質 | Props (プロパティ) | State (ステート) |
| データの発生源 | 親コンポーネントから渡される1 | コンポーネント自身が内部で作成する1 |
| 書き換えの可否 | 受け取ったコンポーネントでは不変 (変更不可)2 | コンポーネント自身で自由に変更できる2 |
| 比喩表現 | 関数の「引数」、外部からの「設定」1 | コンポーネント独自の「ローカル変数」「記憶」1 |
| 更新された時の動き | Propsが変わると、その子コンポーネントが再描画される2 | Stateが変わると、自身と配下の子が再描画される1 |
| 主な用途 | 表示する静的なデータや設定値、コールバック関数1 | フォームの入力値、開閉状態、APIから取得したデータ17 |
「ステートレス」と「ステートフル」のベストプラクティス
Reactのアプリケーションをきれいに保つためのコツは、「できるだけStateを持つコンポーネント(ステートフル)を減らし、Propsを受け取って表示するだけのコンポーネント(ステートレス)を増やす」ことです5。
複雑なデータ処理や状態の管理は、ツリーの上部にある数少ない「ステートフルコンポーネント」に任せ、下部にある多くのコンポーネントは単にPropsを受け取ってきれいに表示することだけに集中させます。こうすることで、データの流れがシンプルになり、テストや修正が非常に楽になります5。
5. コンポーネント間でデータを同期する「ステートの引き上げ」
「2つの異なるコンポーネントで、常に同じデータを同期させて表示したい」という場面がよくあります15。例えば、2つの入力フォームが常に同じ文字を表示する場合などです。
このとき、それぞれのコンポーネントで個別にStateを持たせてしまうと、お互いのデータを同期させることが難しくなります15。このような場合に使うのが、「ステートの引き上げ(Lifting State Up)」というパターンです24。
ステートを引き上げる手順
- 子コンポーネントから独立したStateを削除する: 個々の子コンポーネントで記述していたuseStateを削除し、代わりにそのデータをPropsとして親から受け取るように書き換えます24。
- 共通の親コンポーネントにStateを移動する: 同期させたい2つの子コンポーネントを包んでいる、共通の親(またはさらに上の先祖)コンポーネントを探し、そこにuseStateを宣言します15。
- データと更新用関数を下に流す: 親コンポーネントから子コンポーネントへ、Stateの値と、そのStateを更新するための関数(イベントハンドラ)をそれぞれPropsとして受け渡します15。
具体的なコード例:複数のパネルを同期させるアコーディオン
複数のパネルがあり、「1つのパネルが開いたら、もう片方のパネルは自動的に閉じる」というアコーディオンUIのコード例です。個々のパネルが「自分が開いているか」を管理するのではなく、親が「現在開いているパネルの番号」を管理します24。
JavaScript
// 親コンポーネント:アコーディオン全体
function Accordion() {
// 現在どのインデックス(0番目か1番目か)が開いているかをStateで管理します
const [activeIndex, setActiveIndex] = useState(0);
return (
<>
<Panel
title=”セクション 1″
isActive={activeIndex === 0}
onShow={() => setActiveIndex(0)} // 更新用関数をPropsとして渡します
>
セクション1の詳しいコンテンツです。
</Panel>
<Panel
title=”セクション 2″
isActive={activeIndex === 1}
onShow={() => setActiveIndex(1)}
>
セクション2の詳しいコンテンツです。
</Panel>
</>
);
}
// 子コンポーネント:個々のパネル(自分の開閉状態を自分では決められない「制御された」状態)
function Panel({ title, children, isActive, onShow }) {
return (
<section className=”panel”>
<h3>{title}</h3>
{isActive? (
<p>{children}</p>
) : (
<button onClick={onShow}>表示する</button>
)}
</section>
);
}
このように、データの「信頼できる唯一の情報源(Single Source of Truth)」を親に集約することで、表示の不整合が起きない頑丈なUIが完成します4。
6. バケツリレー(Props Drilling)を防ぐための対策
コンポーネントの階層が5階層、10階層と深くなっていくと、一番上の親から一番下の子にデータを渡すために、途中のコンポーネントたちが自分では使わないPropsをただリレーのようにスルーして渡していくだけの状態が発生します27。
これを「Props Drilling(プロップス・ドリリング、通称:バケツリレー)」と呼び、コードを複雑にしてしまう問題として知られています27。
これに対処するためには、以下の方法が効果的です。
- コンポーネント・コンポジション(構成): 不要な中継コンポーネントを排除し、childrenなどをうまく利用して、データを必要とするコンポーネント自体を親の段階ではめ込んでしまう手法です13。
- Context(コンテキスト)API: Reactに標準搭載されている機能で、ツリーの上の親から、中継コンポーネントをすべてスキップして、直接一番下の子コンポーネントへデータを届ける「ワープトンネル」のような仕組みを作ることができます12。ユーザーのカラーテーマやログイン中のアカウント情報など、アプリ全体で広く使うグローバルなデータ管理に最適です。
7. まとめ:データ設計をシンプルに保つことがReact上達のコツ
React開発の本質は、コンポーネントの分割設計と、データの流れ(PropsとState)をきれいに交通整理することにあります4。
以下のチェックリストを常に頭の片隅に置いて、コードの設計を考えてみてください。
- そのデータは時間とともに変化しますか? 変化しないなら、それは単なる静的な変数や定数であり、Stateにする必要はありません4。
- そのデータは親からPropsで受け取れますか? 受け取れるなら、自身でStateとして二重に持つ必要はありません4。
- 他のStateやPropsから、単純な計算で導き出せますか? 例えば「商品の元の値段」と「割引率」のStateがあれば、「割引後の値段」をわざわざ3つ目のStateとして保存する必要はありません4。レンダリングの最中にその場で引き算をして表示するのが、最もバグの出ない正しい方法です。
Propsによる「設定の外部化」と、Stateによる「状態の自己管理」を上手に使い分け、クリーンでメンテナンスのしやすいReactコードを書いていきましょう!
引用文献
- Component State – React, 5月 7, 2026にアクセス、 https://legacy.reactjs.org/docs/faq-state.html
- Understanding React: Props vs. State | Medium, 5月 7, 2026にアクセス、 https://medium.com/@dudhatrayashraj/props-and-state-in-react-ba9819cbba74
- Components and Props – React, 5月 7, 2026にアクセス、 https://legacy.reactjs.org/docs/components-and-props.html
- Thinking in React – React, 5月 7, 2026にアクセス、 https://react.dev/learn/thinking-in-react
- What is the difference between state and props in React? – Stack Overflow, 5月 7, 2026にアクセス、 https://stackoverflow.com/questions/27991366/what-is-the-difference-between-state-and-props-in-react
- React Props vs State: What’s the Difference? – DEV Community, 5月 7, 2026にアクセス、 https://dev.to/highflyer910/react-props-vs-state-whats-the-difference-4e3i
- What is The Difference Between State and Props in React? – Flatlogic Blog, 5月 7, 2026にアクセス、 https://flatlogic.com/blog/what-is-the-difference-between-state-and-props-in-react/
- Passing Props to a Component – React, 5月 7, 2026にアクセス、 https://react.dev/learn/passing-props-to-a-component
- Props and State in React: Differences and Usage Scenarios | by Tuğçe Çifci | Medium, 5月 7, 2026にアクセス、 https://medium.com/@tucecifcii/props-and-state-in-react-differences-and-usage-scenarios-fb292f74998e
- React Propsとは?たったの「3分」で理解|親子コンポーネントでのデータ渡し方をコード付きで解説 – LifeCode, 5月 7, 2026にアクセス、 https://lifecodeworks.com/tech/react-props-beginner-guide/
- Passing object as props to jsx – reactjs – Stack Overflow, 5月 7, 2026にアクセス、 https://stackoverflow.com/questions/49081549/passing-object-as-props-to-jsx
- Passing props to child components in React function components – CoreUI, 5月 7, 2026にアクセス、 https://coreui.io/blog/passing-props-to-child-components-in-react-function-components/
- 【React】Props のバケツリレー解消法について – Zenn, 5月 7, 2026にアクセス、 https://zenn.dev/rh820/articles/bd8e97fd315cfa
- propsバケツリレー問題をコンポジションで解消し、コンポーネントの単一責務を取り戻す – Zenn, 5月 7, 2026にアクセス、 https://zenn.dev/hmochizuki/articles/a7edd55ed1e459
- Lifting State Up in ReactJS – GeeksforGeeks, 5月 7, 2026にアクセス、 https://www.geeksforgeeks.org/reactjs/lifting-state-up-in-reactjs/
- React入門 – コンポーネント、JSX、Props、Stateの基本 – Zenn, 5月 7, 2026にアクセス、 https://zenn.dev/three_dots_inc/articles/0a479f9dc61bf2
- React Hooks: useState (With Practical Examples) | by Tito Adeoye – Medium, 5月 7, 2026にアクセス、 https://medium.com/@titoadeoye/react-hooks-usestate-with-practical-examples-64abd6df6471
- State(useState)|React入門 2026 – モダンなReact開発を基礎から学ぶ – Zenn, 5月 7, 2026にアクセス、 https://zenn.dev/rasshii/books/learning-react-2026/viewer/07-state
- useState – React, 5月 7, 2026にアクセス、 https://react.dev/reference/react/useState
- React の state とは何かを改めて整理した – Qiita, 5月 7, 2026にアクセス、 https://qiita.com/ryo_sh/items/ef1af33a71b1e4ead816
- Using the State Hook – React, 5月 7, 2026にアクセス、 https://legacy.reactjs.org/docs/hooks-state.html
- Reactのstateとは?更新は即時反映されない。オブジェクト型、プリミティブ型などの注意点 – Qiita, 5月 7, 2026にアクセス、 https://qiita.com/kenogi/items/be5a062524cc7578acd3
- useState in React: A complete guide – LogRocket Blog, 5月 7, 2026にアクセス、 https://blog.logrocket.com/guide-usestate-react/
- Sharing State Between Components – React, 5月 7, 2026にアクセス、 https://react.dev/learn/sharing-state-between-components
- state のリフトアップ – React, 5月 7, 2026にアクセス、 https://ja.legacy.reactjs.org/docs/lifting-state-up.html
- Lesson 4 – Lifting State Up – React Pattern Overview | ReactJS-The Beginner Master Class, 5月 7, 2026にアクセス、 https://reactjs.koida.tech/react-state-and-styling/lesson-4-lifting-state-up-react-pattern-overview
- How props are passed to components in React – LogRocket Blog, 5月 7, 2026にアクセス、 https://blog.logrocket.com/how-props-passed-components-react/
- Reactのprops drilling(バケツリレー)とhooksに我々はどう立ち向かっていけばよいのか, 5月 7, 2026にアクセス、 https://blog.asobou.co.jp/web/props-drilling
- ReactでContext APIを使う前にやるべきprops drilling問題の解消法 – i3DESIGN Tech Blog, 5月 7, 2026にアクセス、 https://tech.i3design.jp/react-props-drilling-composition/




