【4日目】React初学者が1週間でどこまで出来るか挑戦(Createフォーム作成)
公開: 2023-10-10
更新: 2023-10-14
はじめに
React学習1週間チャレンジ4日目です。Inertiaを活用してCreateフォーム、Store処理の実装までできました。平日仕事終わりはやる気はあるんですが完全に眠気との戦いです。
前回の振り返り:
-
【3日目】React初学者が1週間でどこまで出来るか挑戦(Inertiaの理解)
- Inertia, ReactをLaravelにマニュアルでインストール(Breezeを使わず)
- Userデータを取り出して一覧で表示
- オリジナルのレイアウトを作成
- InertiaのPersistent layoutsでSPA実現
Createフォームを作る
InertiaのuseFromメソッド
InertiaのFormヘルパuseForm
が使うのが簡単らしい。
まずはuserForm
の理解を深める。
import { useForm } from '@inertiajs/react'
const { data, setData, post, processing, errors } = useForm({
email: '',
password: '',
remember: false,
})
分割代入構文
まずこの記法を理解できなかったため、JavaScriptの分割代入 (Destructuring assignment) 構文について調べた。
オブジェクトからプロパティを取り出して別個の変数に代入できる。プロパティの名前に基づいてバインドされるためプロパティ順番は入れ替えてもOK。
// Example
const object = {name: 'Ryosuke', like: 'Coffee'};
const {name, like} = object;
console.log(name); // Ryosuke
console.log(like); // Coffee
Inertiaのコードを再度見ると、useForm
はInertiaFormProps
オブジェクトを返しており、そのオブジェクトに定義されたdata
オブジェクトやsetData
などを分割代入していたということだ。
const { data, setData, post, processing, errors } = useForm({ ... });
フォームを作る
次に、フォームを送信するためにsubmit
という関数を定義する。上記で定義されたpost
の第一引数にURLを指定する。
const submit = (e) => {
e.preventDefault();
post('/users/store')
};
あとは入力用Inputを作る。
return (
<>
<h1 className="title title-h1">User 登録</h1>
<form onSubmit={submit}>
<input type="text"
name=""
value={data.name}
className='input-field'
onChange={(e) => setData('name', e.target.value)}
required
/>
<div className='invalid-feedback'>{errors.name}</div>
{/* 他のInputは省略 */}
<button className='btn btn-store'>
登録
</button>
</form>
</>
);
ポイントは、
-
onSubmit={submit}
: フォームが送信されたときにsubmit
関数を呼び出すように設定。submit
関数の中で、e.preventDefault();
が呼び出されることで、フォームのデフォルトの送信動作(ページのリロード)がキャンセルされ、代わりにpost('/users/store')
が実行される。 -
value={data.name}
:input
要素の現在の値をdata.name
にバインドしている。フォームの状態(data
オブジェクト)とinput
要素の表示が同期される。input
フィールドが入力されると、その値はdata.name
に反映される。 -
onChange={(e) => setData('name', e.target.value)}
:input
要素の値が変更されるたび(ユーザーがテキストを入力/編集するたび)に実行されるイベントハンドラー。具体的には、入力された新しい値e.target.value
をsetData
関数を使ってdata.name
にセット。これにより、ユーザーの入力がdata
オブジェクトに即座に反映される。 -
{errors.name}
:name
フィールドに関連するエラーメッセージを表示する。name
フィールドにバリデーションエラーなどがあればerrors.name
に格納される。 -
disabled={processing}
:processing
はフォームが送信中の間はtrue
を返す。disabled
がtrueの時HTMLのdisabled
属性が有効になってボタンを無効にしている。 参考: input– React
送信されたリクエストをもとにユーザーデータを作成する方法は、通常のLaravel側の処理を書くだけ。
// UserController
public function store(UserStoreRequest $request)
{
$user = User::create([
'name' => $request->input('name'),
'email' => $request->input('email'),
'password' => Hash::make($request->input('password')),
]);
return to_route('users.index');
}
Formへルパの活用
InertiaのFormへルパの使い方を少し見ていきます。
isDirty
はフォームに変更がある場合にtrue
を返す。これを使えば、フォームに変更が加わるまでは登録ボタンをdisabled
にしておくことができる。
const { isDirty } = useForm({ ... })
<button className='btn btn-store' disabled={!isDirty}>
登録
</button>
wasSuccessful
プロパティはフォーム送信成功時にtrue
を返す。これを使えば登録成功アラートを出すことができる。
const { wasSuccessful } = useForm({})
{wasSuccessful && <div className="alert alert-success">登録成功</div>}
ただ、今回はサーバー側で登録処理完了後にroute('users.index)'
へリダイレクトさせるため不要。
連載記事
- 【1日目】React初学者が1週間でどこまで出来るか挑戦
- 【2日目】React初学者が1週間でどこまで出来るか挑戦(ひたすらドキュメント編)
- 【3日目】React初学者が1週間でどこまで出来るか挑戦(Inertiaの理解)
- 【4日目】React初学者が1週間でどこまで出来るか挑戦(Createフォーム作成)
- 【5日目】React初学者が1週間でどこまで出来るか挑戦(Createフォーム改善)