Reactで学ぶPropsとStateの型安全リファクタリング!初心者でもわかる安全な書き直し方法
生徒
「Reactのコードが増えてきたら、PropsやStateがごちゃごちゃしてきました…。書き直したほうがいいんですか?」
先生
「それがリファクタリングです。動きを変えずに、読みやすく安全に整える作業ですね。」
生徒
「TypeScriptを使っていると、型も関係してきますよね?」
先生
「はい。PropsとStateを型安全にリファクタリングすると、ミスが減って修正もしやすくなります。基本から順番に見ていきましょう。」
1. リファクタリングとは?React初心者向け解説
リファクタリングとは、プログラムの動きを変えずに、中身を整理して読みやすくすることです。Reactでは、コンポーネントが増えたり、PropsやStateが増えたりすると、最初は動いていても後から直しにくくなります。
たとえば、引き出しに物を適当に入れていると、最初は便利でも、あとで探すのが大変になります。リファクタリングは、引き出しの中を整理して「どこに何があるか」を分かりやすくする作業です。
TypeScriptを使っている場合は、型も一緒に整理することで、Reactのコードをより安全にできます。
2. 型安全にリファクタリングする理由
ReactでPropsやStateを型安全にしておくと、間違った値の受け渡しを防げます。しかし、書き方がバラバラだったり、同じような型を何度も書いていたりすると、かえって分かりにくくなります。
型安全なリファクタリングの目的は、次の3つです。
- 同じ形のデータは同じ型を使う
- PropsとStateの役割をはっきり分ける
- 修正したときにエラーで気づける状態を保つ
これらを意識することで、React初心者でも安心してコードを整理できます。
3. よくあるリファクタリング前の状態
まずは、リファクタリング前によくある状態を見てみます。PropsとStateの型がその場その場で書かれているケースです。
import React, { useState } from "react";
function UserCard(props: { name: string; age: number }) {
const [userName, setUserName] = useState<string>(props.name);
return (
<div>
<p>{userName}({props.age}歳)</p>
<button onClick={() => setUserName("さくら")}>
名前変更
</button>
</div>
);
}
export default UserCard;
このコードは動きますが、「nameとageのまとまり」がPropsとStateで分かれていて、後から項目が増えると修正が大変になります。
4. 共通の型を作って整理する
リファクタリングの第一歩は、共通の型を作ることです。PropsとStateで同じ意味のデータを扱うなら、同じ型を使います。
type User = {
name: string;
age: number;
};
この型を使って、PropsとStateを整理します。
type UserCardProps = {
user: User;
};
function UserCard(props: UserCardProps) {
const [currentUser, setCurrentUser] = useState<User>(props.user);
return (
<div>
<p>{currentUser.name}({currentUser.age}歳)</p>
<button
onClick={() =>
setCurrentUser({ ...currentUser, name: "さくら" })
}
>
名前変更
</button>
</div>
);
}
こうすることで、「ユーザー情報はUser型」というルールがはっきりします。項目が増えても、User型を直すだけで済みます。
5. PropsからStateを作る処理を見直す
リファクタリングでは、「PropsをそのままStateにしていないか」を確認することも大切です。Propsは外からの情報、Stateは内部の状態なので、役割が違います。
「初期値として使うだけ」なら問題ありませんが、「常に同期したい」場合は、Stateを持たない設計の方が分かりやすいこともあります。
型安全なリファクタリングでは、「誰がデータを持つのか」を整理すると、型の数も自然に減っていきます。
6. 親のStateをPropsで受け取る形に直す
次は、親がStateを持ち、子はPropsで受け取る形へのリファクタリングです。この形はReactでとてもよく使われます。
type DisplayProps = {
text: string;
onChangeText: (value: string) => void;
};
function Display(props: DisplayProps) {
return (
<div>
<p>{props.text}</p>
<button onClick={() => props.onChangeText("こんにちは")}>
変更
</button>
</div>
);
}
export default function App() {
const [text, setText] = useState<string>("");
return <Display text={text} onChangeText={setText} />;
}
更新用の関数も型で指定することで、子が間違った値を渡すのを防げます。これも型安全なリファクタリングの重要なポイントです。
7. Propsの型を読みやすくする工夫
リファクタリングでは、Propsの型名も大切です。「Props」という名前だけでなく、「何のPropsか」が分かる名前にすると読みやすくなります。
また、optionalなPropsがある場合は、「なくてもいい理由」が分かるように設計します。初期値を決めておくと、Stateとの組み合わせもシンプルになります。
型は説明書のようなものなので、見ただけで役割が伝わることが理想です。
8. リファクタリングで減らせるバグの例
型安全にPropsとStateを整理すると、次のようなバグを減らせます。
- 間違った型の値を渡してしまうミス
- オブジェクトの項目名の書き間違い
- 更新関数の使い方の間違い
TypeScriptは、リファクタリング中にエラーを教えてくれるので、「どこを直せばいいか」が分かりやすくなります。
9. 初心者向け:安全にリファクタリングする手順
React初心者の方は、次の順番でリファクタリングすると安心です。
- 同じ形のデータを探す
- 共通の型を1つ作る
- PropsとStateでその型を使う
- 更新関数の型を明確にする
一度に全部直そうとせず、小さなコンポーネントから進めるのがコツです。
10. PropsとStateの型安全リファクタリングがもたらす安心感
PropsとStateを型安全にリファクタリングすると、Reactのコードは「壊れにくく」「読みやすく」なります。最初は少し手間に感じても、後から修正する時間が大きく減ります。
ReactとTypeScriptの組み合わせは、初心者でも安心してコードを書ける環境を作ってくれます。リファクタリングは怖い作業ではなく、コードを育てる作業だと考えると、取り組みやすくなります。