Reactで学ぶ型安全なPropsとState管理まとめ!TypeScriptで安心して開発する基本
生徒
「ReactとTypeScriptでPropsとStateを安全にしたいんですが、結局どこを押さえればいいですか?」
先生
「大事なのは、Propsは受け取る箱、Stateは自分の中のメモ、という役割を守ることです。」
生徒
「型を付けるとエラーが減るのは分かるけど、何から整えるのが近道ですか?」
先生
「基本の型定義、初期値、更新関数、そしてデータが無い状態の扱い。この四つを順番に整理しましょう。」
1. PropsとStateの役割を一言で整理する
Reactでは、Propsは外から受け取る情報で、Stateは画面の中で変わる情報です。まずこの役割を混ぜないことが、型安全の土台になります。
Propsはプレゼントの箱のようなもので、渡された内容を勝手に書き換えません。Stateは自分用のメモ帳で、ボタン操作や入力によって中身が増えたり変わったりします。
TypeScriptの型は、その箱やメモ帳に入れてよい物を決めるルールです。ルールがあると、間違った物を入れそうになった時にすぐ止めてくれます。
特に初心者のうちは、PropsとStateがどちらも変数に見えてしまい、同じように扱ってしまいがちです。しかし、Propsは親から子へ渡す伝言で、Stateは自分の部屋のスイッチの状態です。伝言を書き換えると親と子で話がずれてしまいますが、スイッチは自分で自由に切り替えられます。
この違いを意識すると、どこに型を付けるべきかも見えてきます。Propsは受け取る時点で形が決まるので、型を付けるとこの部品はこう使うという説明になります。Stateは変化するので、型を付けるとこの部品の中で変わるのはこれだけという境界線になります。
2. Propsの型安全はまず型名を作るところから
Propsを型安全にするコツは、いきなり関数の引数に型を書くのではなく、Props用の型名を作って分かりやすくすることです。型名があると、画面の部品が増えても読み間違いが減ります。
type GreetingProps = {
name: string;
};
function Greeting(props: GreetingProps) {
return <h2>こんにちは、{props.name}さん</h2>;
}
ここで大切なのは、Propsの型がその部品の使い方の説明書になる点です。渡すべき情報が一目で分かるので、開発が安全になります。
3. Stateは初期値と型指定の組み合わせで迷子を防ぐ
Stateは初期値を見て型が決まることが多いです。文字なら文字、数なら数として扱われます。ところが、最初が空の状態だと型があいまいになり、エラーの原因になりやすいです。
初心者のうちは、Stateに何を入れたいのかを言葉で決めてから、初期値と型をセットで考えると安全です。
import React, { useState } from "react";
function Counter() {
const [count, setCount] = useState<number>(0);
return (
<div>
<p>現在の数:{count}</p>
<button onClick={() => setCount(count + 1)}>増やす</button>
</div>
);
}
export default Counter;
数を入れる箱だと決めたら、文字を入れる操作は間違いになります。型はその間違いを早い段階で教えてくれます。
型推論という言葉もよく出ます。型推論は最初に入れた値から、型を自動で決めてくれる仕組みです。たとえば最初が文字なら、以後も文字として扱われます。便利ですが、初期値が空だったり、途中で別の形を入れたくなったりすると困ります。そのため、迷いそうなStateは最初から型指定しておくと安心です。
Stateは用途ごとに箱を分けるほうが安全です。読み込み中を表す真偽値、エラーを表す文字、取得したデータを表す配列など、役割が違うものを分けると、画面の表示も分かりやすくなります。
4. 入力フォームはオブジェクトのStateでまとめると型が強くなる
フォーム入力は、名前や年齢や同意など複数の値を扱います。Stateを一つずつ増やすより、オブジェクトにまとめて型を一つにすると整理しやすいです。
オブジェクトの型を作ると、どの入力が文字で、どの入力が数かがはっきりします。あとから項目が増えても、型を見れば全体の形が分かります。
import React, { useState } from "react";
type FormState = {
name: string;
age: number;
agree: boolean;
};
function ProfileForm() {
const [form, setForm] = useState<FormState>({
name: "",
age: 0,
agree: false
});
return (
<div>
<input
type="text"
value={form.name}
onChange={(e) => setForm({ ...form, name: e.target.value })}
/>
<input
type="number"
value={form.age}
onChange={(e) => setForm({ ...form, age: Number(e.target.value) })}
/>
<label>
<input
type="checkbox"
checked={form.agree}
onChange={(e) => setForm({ ...form, agree: e.target.checked })}
/>
同意する
</label>
<p>名前:{form.name}</p>
<p>年齢:{form.age}</p>
<p>同意:{form.agree ? "はい" : "いいえ"}</p>
</div>
);
}
export default ProfileForm;
5. 非同期データは「まだ無い」を前提に型を決める
APIからデータを取ってくる時は、最初はデータがありません。だからStateは、データが入る前の形も想像して作ります。
たとえば一覧なら空の配列から始めると扱いやすいです。一件だけなら、空の状態を表す値としてnullを使い、型に含めます。
この考え方ができると、画面が真っ白になったり、存在しない値を読んでしまう失敗が減ります。
非同期は、待ち時間があっても画面を動かせる仕組みです。
型安全にするコツは、データそのものの型だけでなく、状態の型も考えることです。たとえば読み込み中成功失敗をそれぞれ別のStateで持つと、表示の分け方がはっきりします。最初に無い状態を丁寧に作ると、あとから条件分岐が楽になります。
6. 更新関数の型は「どう変えるか」を安全にする
Stateを変える時は、更新関数を使います。ここでの失敗は、古い値のまま計算したり、オブジェクトの一部だけを書き換えて壊したりすることです。
型安全にするためには、Stateの形を守ったまま更新する意識が大切です。オブジェクトなら、元の値を広げて必要な部分だけ上書きします。これを守ると、項目の抜けや書き間違いが起きにくくなります。
更新関数には、直接新しい値を渡す方法と、前の値から計算して作る方法があります。カウントのように前の値に足す場合は、前の値を使う書き方にしておくと、連続クリックでもずれにくくなります。型は計算の材料が正しい種類かどうかも見張ってくれます。
Propsで受け取った関数をState更新に使う場面では、引数の型を決めておくと呼び出しミスを防げます。
7. よくある型エラーは「箱のルール違反」と考える
型エラーが出た時は、怒られているのではなく、箱のルールに合っていないだけです。文字の箱に数を入れた、必須のPropsを渡し忘れた、まだ無いデータを使おうとした、などが代表例です。
エラー文は難しく見えますが、どの場所で何が合っていないかを指しています。まずはその行を見て、型名と値の形が合っているかを確認すると解決しやすいです。
8. 型安全を続けるための小さなチェック項目
最後に、PropsとStateを型安全に保つためのチェック項目をまとめます。難しい道具を増やすより、毎回ここを確認するだけで安定します。
- Propsは型名を作り、必要な情報だけを受け取る
- Stateは初期値をはっきり決め、あいまいさを残さない
- フォームはオブジェクトでまとめ、全体の形を型で固定する
- 非同期は最初に無い状態を想定し、配列やnullで表す
- 更新は形を壊さない方法を守り、部分更新を丁寧に行う
この流れを覚えると、ReactとTypeScriptの型安全なPropsとState管理が、怖いものではなく心強い味方になります。
9. ジェネリック型は「型の型」として理解すると怖くない
ジェネリック型は難しく見えますが、考え方は単純です。あとで中身の型を決められる箱を作る仕組みです。たとえば配列は、中に入る型が文字か数かで使い方が変わります。ジェネリック型は、その違いを安全に表せます。
Reactでは、useStateにジェネリック型を指定して、最初は空でも後から入る形を決めることがあります。特に、空配列から始めたい時や、nullから始めたい時に役立ちます。最初に型を決めておくことで、後から入るデータがぶれなくなります。
まずは必要な場面でだけ使うと読みやすさを保てます。
10. 型安全はテストとリファクタリングの味方になる
型安全に整えたPropsとStateは、テストでも役立ちます。テストは動きが正しいかを確かめる作業ですが、型があると間違った使い方そのものが書けなくなります。つまり、失敗が減ります。
また、コードを整理するリファクタリングでも安心感が増えます。型が説明書になっているので、Propsを追加したりStateの形を変えたりした時に、直すべき場所がエラーとして見つかります。目で探すより確実です。
ReactとTypeScriptの組み合わせは、初心者でも安全に成長できる環境を作れます。箱の役割を守り、初期値を決め、無い状態を想定し、更新の形を壊さない。この流れを繰り返すことが、型安全なPropsとState管理を身につける一番の近道です。