✅ はじめに
こんにちは!このシリーズでは、React + Vite + TypeScript + MUIを使ってモダンなWebアプリを開発する方法をステップバイステップで解説しています。
第5回となる今回は、「React Hook Formを使った複数メールアドレスの入力フォーム」を実装します。useFieldArray
を使用した動的なフォーム要素の追加・削除と、効果的なバリデーション処理を学びます。
📦 使用する技術スタック
ツール | バージョン | 説明 |
---|---|---|
React Hook Form | v7.x | 高性能なフォームバリデーションライブラリ |
MUI | v5.x | マテリアルデザインベースのUIコンポーネント |
TypeScript | 5.x | 型安全なJavaScript |
Vite | 5.x | 高速な開発環境とビルドツール |
🚀 実装手順
1. プロジェクトの作成
まずは、Viteを使って新しいプロジェクトを作成します:
npm create vite@latest react-form-advanced -- --template react-ts cd react-form-advanced npm install
2. 必要なパッケージのインストール
MUIとReact Hook Formをインストールします:
npm install @mui/material @emotion/react @emotion/styled @mui/icons-material react-hook-form @fontsource/roboto
3. 複数メール入力フォームの作成
src/AdvancedForm.tsxを作成します:
import type { FC } from "react" import { useForm, useFieldArray } from "react-hook-form" import { Box, Button, Container, TextField, Typography, } from "@mui/material" import { Add, Delete } from "@mui/icons-material" type FormValues = { name: string emails: { email: string }[] } const AdvancedForm: FC = () => { const { register, control, handleSubmit, formState: { errors }, } = useForm<FormValues>({ defaultValues: { name: "", emails: [{ email: "" }], }, }) const { fields, append, remove } = useFieldArray({ control, name: "emails", }) const onSubmit = (data: FormValues) => { console.log("送信データ:", data) alert(JSON.stringify(data, null, 2)) } return ( <Container maxWidth="sm"> <Box mt={5}> <Typography variant="h5" gutterBottom> 高度なフォーム(React Hook Form + MUI) </Typography> <form onSubmit={handleSubmit(onSubmit)} noValidate> <Box display="flex" flexDirection="column" gap={2}> <Box> <TextField fullWidth label="名前" {...register("name", { required: "名前は必須です" })} error={Boolean(errors.name)} helperText={errors.name?.message} /> </Box> {fields.map((field, index) => ( <Box key={field.id}> <Box display="flex" alignItems="center" gap={1}> <TextField fullWidth label={`メール ${index + 1}`} {...register(`emails.${index}.email`, { required: "メールは必須です", pattern: { value: /^[^\s@]+@[^\s@]+\.[^\s@]+$/, message: "メール形式が不正です", }, })} error={Boolean(errors.emails?.[index]?.email)} helperText={errors.emails?.[index]?.email?.message} /> <Button variant="outlined" color="secondary" onClick={() => remove(index)} > <Delete /> </Button> </Box> </Box> ))} <Box> <Button variant="outlined" startIcon={<Add />} onClick={() => append({ email: "" })} > メール追加 </Button> </Box> <Box mt={2} display="flex" justifyContent="center"> <Button type="submit" variant="contained" color="primary"> 送信 </Button> </Box> </Box> </form> </Box> </Container> ) } export default AdvancedForm
4. App.tsxの更新
src/App.tsxを更新してフォームを表示します:
import { ThemeProvider, createTheme } from '@mui/material' import AdvancedForm from "./AdvancedForm" import '@fontsource/roboto/300.css' import '@fontsource/roboto/400.css' import '@fontsource/roboto/500.css' import '@fontsource/roboto/700.css' const theme = createTheme({ typography: { fontFamily: '"Roboto", "Helvetica", "Arial", sans-serif', }, }) function App() { return ( <ThemeProvider theme={theme}> <AdvancedForm /> </ThemeProvider> ) } export default App
🎯 主要なポイント
1. フォーム状態管理
- useForm: フォーム全体の状態とバリデーション管理
- useFieldArray: 動的なフィールド配列の管理
- 型安全な実装: TypeScriptによる型定義
2. バリデーション機能
- 必須チェック: 名前とメールアドレスの入力必須
- メール形式: 正規表現によるメールアドレス形式の検証
- 視覚的フィードバック: エラーメッセージの即時表示
3. UIコンポーネント
- TextField: 入力フィールドとエラー表示の統合
- Button: アイコン付きの操作ボタン
- 動的なUI: フィールドの追加・削除機能
🔚 まとめ
今回は、React Hook Form の useFieldArray
を使って、複数メール入力のフォームを実装しました。
動的なフォーム要素の管理とバリデーション処理を効率的に実装できることが分かりました。
📚 次回予告
【第6回】バリデーション結果をモーダルで表示するReact Hook Form実装