はじめに
このハンズオンでは、Reactを使ってフォームを作成し、React Hook FormとZodを使ってバリデーションを実装する方法を学びます。また、Chakra UIを使ってスタイリッシュなフォームを構築します。これにより、効率的で信頼性の高いフォームバリデーションとデザインが可能になります。
学ぶこと
- React Hook Formの基本的な使い方
- Zodを使ったスキーマベースのバリデーション
- Chakra UIを使ったデザインの強化
- React Hook Formの
control
を使用したサードパーティコンポーネントの連携方法
対象読者
- ReactとTypeScriptの基本的な知識がある方
- フォームバリデーションを実装したい方
- React Hook FormとZodの使い方を学びたい方
- Chakra UIを使ったデザインを学びたい方
技術スタック
- React
- TypeScript
- React Hook Form
- Zod
- Chakra UI
公式ドキュメント
プロジェクトのセットアップ
まず、必要なパッケージをインストールします。
npx create-react-app my-form-app --template typescript
cd my-form-app
yarn add @chakra-ui/react @emotion/react @emotion/styled framer-motion
yarn add react-hook-form zod @hookform/resolvers
完成のイメージ
Chakra UI のセットアップ
次に、Chakra UIをプロジェクトに設定します。src/index.tsx
ファイルを開き、以下のように変更します。
import React from 'react';
import ReactDOM from 'react-dom';
import { ChakraProvider } from '@chakra-ui/react';
import App from './App';
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
root.render(
<ChakraProvider>
<App />
</ChakraProvider>
);
フォームの作成
このセクションでは、React Hook FormとZodを使用してフォームバリデーションを実装し、Chakra UIを使用してフォームをスタイリングする方法を学びます。以下に、全体のコードとその各部分の解説を示します。
1. 全体のコード
まず、src/App.tsx
に以下のコードを追加します。
import React from 'react';
import { useForm, SubmitHandler, Controller } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import { Box, Button, FormControl, FormErrorMessage, FormLabel, Input } from '@chakra-ui/react';
// Zodスキーマを定義
const schema = z.object({
name: z.string().min(1, '名前は必須です'),
email: z.string().email('有効なメールアドレスを入力してください'),
password: z.string().min(6, 'パスワードは6文字以上で入力してください')
});
// FormDataはスキーマに基づいて生成された型
type FormData = z.infer<typeof schema>;
const App: React.FC = () => {
// useFormの初期化
const { control, handleSubmit, formState: { errors } } = useForm<FormData>({
resolver: zodResolver(schema),
defaultValues: {
name: '',
email: '',
password: ''
}
});
const onSubmit: SubmitHandler<FormData> = data => {
console.log(data);
};
return (
<Box maxW="md" mx="auto" mt="10">
<form onSubmit={handleSubmit(onSubmit)}>
<Controller
name="name"
control={control}
render={({ field }) => (
<FormControl isInvalid={!!errors.name} mb="4">
<FormLabel htmlFor="name">名前</FormLabel>
<Input id="name" {...field} />
<FormErrorMessage>{errors.name && errors.name.message}</FormErrorMessage>
</FormControl>
)}
/>
<Controller
name="email"
control={control}
render={({ field }) => (
<FormControl isInvalid={!!errors.email} mb="4">
<FormLabel htmlFor="email">メールアドレス</FormLabel>
<Input id="email" {...field} />
<FormErrorMessage>{errors.email && errors.email.message}</FormErrorMessage>
</FormControl>
)}
/>
<Controller
name="password"
control={control}
render={({ field }) => (
<FormControl isInvalid={!!errors.password} mb="4">
<FormLabel htmlFor="password">パスワード</FormLabel>
<Input id="password" type="password" {...field} />
<FormErrorMessage>{errors.password && errors.password.message}</FormErrorMessage>
</FormControl>
)}
/>
<Button mt="4" colorScheme="teal" type="submit">送信</Button>
</form>
</Box>
);
};
export default App;
2. 各コード・機能の解説
src/App.tsx
について細かく解説していきます。
1. Zodの設定
まず、Zodを使用してバリデーションスキーマを定義します。これにより、各フォームフィールドに対するバリデーションルールを指定できます。
import { z } from 'zod';
// Zodスキーマを定義
const schema = z.object({
name: z.string().min(1, '名前は必須です'),
email: z.string().email('有効なメールアドレスを入力してください'),
password: z.string().min(6, 'パスワードは6文字以上で入力してください')
});
// FormDataはスキーマに基づいて生成された型
type FormData = z.infer<typeof schema>;
-
z.object({...})
: オブジェクトスキーマを定義します。 -
z.string().min(1, '名前は必須です')
: 文字列が少なくとも1文字であることをバリデートします。 -
z.string().email('有効なメールアドレスを入力してください')
: 有効なメールアドレス形式であることをバリデートします。 -
z.string().min(6, 'パスワードは6文字以上で入力してください')
: 文字列が少なくとも6文字であることをバリデートします。 -
type FormData = z.infer<typeof schema>
: Zodスキーマに基づいて生成された型です。
2. React Hook Formの設定
次に、React Hook Formを使用してフォームを管理します。useForm
フックを使用してフォームの初期化とバリデーションを設定します。
import { useForm, SubmitHandler, Controller } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
// useFormの初期化
const { control, handleSubmit, formState: { errors } } = useForm<FormData>({
resolver: zodResolver(schema),
defaultValues: {
name: '',
email: '',
password: ''
}
});
-
useForm<FormData>
: React Hook Formのフックを呼び出し、フォームの状態を管理します。 -
resolver: zodResolver(schema)
: Zodスキーマを使用してバリデーションを行うためのリゾルバを設定します。 -
defaultValues
: フォームの初期値を設定します。 -
control
: React Hook Formのcontrol
オブジェクトを使用して、外部コンポーネントと連携します。 -
handleSubmit
: フォームの送信を処理する関数です。 -
formState: { errors }
: フォームのエラーステートを取得します。
3. フォームの実装
最後に、Chakra UIを使用してフォームを実装します。Controller
コンポーネントを使用して、React Hook FormとChakra UIのフォームコンポーネントを連携させます。
import { Box, Button, FormControl, FormErrorMessage, FormLabel, Input } from '@chakra-ui/react';
const App: React.FC = () => {
const onSubmit: SubmitHandler<FormData> = data => {
console.log(data);
};
return (
<Box maxW="md" mx="auto" mt="10">
<form onSubmit={handleSubmit(onSubmit)}>
<Controller
name="name"
control={control}
render={({ field }) => (
<FormControl isInvalid={!!errors.name} mb="4">
<FormLabel htmlFor="name">名前</FormLabel>
<Input id="name" {...field} />
<FormErrorMessage>{errors.name && errors.name.message}</FormErrorMessage>
</FormControl>
)}
/>
<Controller
name="email"
control={control}
render={({ field }) => (
<FormControl isInvalid={!!errors.email} mb="4">
<FormLabel htmlFor="email">メールアドレス</FormLabel>
<Input id="email" {...field} />
<FormErrorMessage>{errors.email && errors.email.message}</FormErrorMessage>
</FormControl>
)}
/>
<Controller
name="password"
control={control}
render={({ field }) => (
<FormControl isInvalid={!!errors.password} mb="4">
<FormLabel htmlFor="password">パスワード</FormLabel>
<Input id="password" type="password" {...field} />
<FormErrorMessage>{errors.password && errors.password.message}</FormErrorMessage>
</FormControl>
)}
/>
<Button mt="4" colorScheme="teal" type="submit">送信</Button>
</form>
</Box>
);
};
export default App;
-
Controller
: React Hook Formのコンポーネントで、フォームフィールドと外部コンポーネントを連携させます。 -
FormControl
: Chakra UIのコンポーネントで、フォームフィールドをラップします。 -
FormLabel
: フィールドのラベルを表示します。 -
Input
: ユーザーが入力するためのテキストボックスです。 -
FormErrorMessage
: バリデーションエラーメッセージを表示します。
これで、React Hook FormとZodを使用したバリデーション込みのフォームが完成しました。Chakra UIを使用してフォームをスタイリングし、使いやすいインターフェースを提供します。
まとめ
このハンズオンでは、React、React Hook Form、Zod、Chakra UIを使ってバリデーション込みのフォームを作成しました。これにより、効率的で信頼性の高いフォームバリデーションとスタイリッシュなデザインを簡単に実装することができます。また、React Hook Formのcontrol
を使用することで、サードパーティのコンポーネントとの連携もスムーズに行うことが可能になります。
次に、フォームをさらに改造していろいろなフィールドを追加したり、送信後の処理を実装したりして、自分のアプリケーションに合わせてカスタマイズしてみてください。