ReactとTypeScriptの組み合わせは、現代のフロントエンド開発において最もポピュラーな選択肢の一つです。型安全性と高い開発体験を実現しながら、スケーラブルなWebアプリを構築できます。
React + TypeScript環境のセットアップ
# Viteを使ったセットアップ(推奨)
npm create vite@latest my-app -- --template react-ts
cd my-app
npm install
npm run dev
# Create React App(レガシー)
npx create-react-app my-app --template typescript
TypeScriptの型定義基礎
// 基本的な型定義
interface User {
id: number;
name: string;
email: string;
role: "admin" | "user" | "guest";
createdAt: Date;
address?: string; // オプショナル
}
// 関数の型定義
type FetchUser = (id: number) => Promise;
// ジェネリック型
type ApiResponse = {
data: T;
status: number;
message: string;
};
type UserResponse = ApiResponse;
type UsersResponse = ApiResponse;
Reactコンポーネントの書き方(TypeScript対応)
// 関数コンポーネント + Props型定義
interface ButtonProps {
label: string;
onClick: () => void;
variant?: "primary" | "secondary" | "danger";
disabled?: boolean;
children?: React.ReactNode;
}
const Button: React.FC = ({
label,
onClick,
variant = "primary",
disabled = false,
}) => {
return (
);
};
export default Button;
React Hooks完全ガイド
import React, { useState, useEffect, useCallback, useMemo } from "react";
interface Todo {
id: number;
text: string;
completed: boolean;
}
const TodoApp: React.FC = () => {
const [todos, setTodos] = useState([]);
const [input, setInput] = useState("");
const [loading, setLoading] = useState(false);
// useEffect: 副作用処理
useEffect(() => {
const saved = localStorage.getItem("todos");
if (saved) setTodos(JSON.parse(saved));
}, []);
// useCallback: 関数をメモ化
const addTodo = useCallback(() => {
if (!input.trim()) return;
const newTodo: Todo = { id: Date.now(), text: input, completed: false };
setTodos(prev => [...prev, newTodo]);
setInput("");
}, [input]);
// useMemo: 計算結果をメモ化
const completedCount = useMemo(
() => todos.filter(t => t.completed).length,
[todos]
);
return (
Todo App ({completedCount}/{todos.length}完了)
setInput(e.target.value)} />
);
};
カスタムフックの作成
// useFetch: データ取得の汎用カスタムフック
function useFetch(url: string) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const controller = new AbortController();
fetch(url, { signal: controller.signal })
.then(res => res.json())
.then(setData)
.catch(err => {
if (err.name !== "AbortError") setError(err);
})
.finally(() => setLoading(false));
return () => controller.abort();
}, [url]);
return { data, loading, error };
}
// 使用例
const { data: users, loading } = useFetch("/api/users");
まとめ
React + TypeScriptは現代フロントエンド開発の標準的な組み合わせです。TypeScriptの型安全性とReactのコンポーネントベースの設計を組み合わせることで、保守性が高く信頼性のあるアプリケーションを構築できます。本記事で学んだパターンを活用して、本格的なReactアプリ開発に挑戦してみてください。