FrontEnd

Remixでフォーム作るならConformが良いらしいので試してみた

投稿日:

はじめに

最近、Remixをいじり始めました。その中でFormの実装にはConformというライブラリを使った方が良い、という情報が多かったので、実際どうなのか試してみました。

まずは、Remixでベーシックなフォームとバリデーションを作り、今度はそれをConformを使って作ってみる、という方法で比較してみたいと思います。

Conformを使わずにフォームを実装

サンプル実装

まずは、loaderまで実装します。

loaderでは、データベースを模したconst profileDB をそのまま返すのみです。

次に、actionを実装します。

actionはサーバサイドで実行されるため、リクエストされてきた値にはバリデーションをかける必要があります。

まず、フォームの値は formData.get("name") のように取得できるのですが、この時点での型は File | string | null となっています。
今回のフォームは文字列であるため、 ?.toString() することでひとまず string | null になります。
数値や日時も一旦 string になってしまうため、必要に応じてパースする必要があります。

バリデーションでは、必須チェックと文字数チェックをしています。チェックに引っかかった場合は、 return json() でメッセージをレスポンスします。

バリデーションが全て通った場合のみ、データを保存し、メッセージをレスポンスして終了です。

最後に、コンポーネントのコードです。

Joy UIを使っていますが、シンプルなフォームになっています。

先ほどのactionのレスポンスを表示するため、 useActionData<typeof action>() を使っています。

また、クライアントでのバリデーションはHTMLの標準機能を使っています。基本的にはこのバリデーションが効いているため、サーバサイドでバリデーションエラーとなることはありませんが、このバリデーションを外すことで、actionのバリデーションを試すことができます。

このコードの辛い点

ひとまず、Remixのドキュメントを参考にしながらこのコードを書いてみて、以下の点が辛いなと思いました。

  • actionで受け取ることができるフォームの型が File | string | null となっていて、数値や日付の場合はパースする必要がある
  • actionとコンポーネントで、同じバリデーションルールをそれぞれ書く必要がある

サーバサイドとクライアントサイドが別のアプリケーションである場合は、スキーマ駆動開発によってこの2点を解消することができると思います。
Remixの場合は、こういった辛い点をConformを使って乗り切るみたいです。

Conformを使ってみる

ConformはRemixやNext.jsに対応する、型安全なフォームバリデーションライブラリです。バリデーション部分はZodに依存しているのですが、actionやコンポーネントの実装に便利な関数が用意されていて、Remixとうまく統合することができるみたいです。
実際に試してみましょう。

サンプルコード

それでは先ほどのフォームをConformを使って実装してみます。loaderまでは同じなので省略し、actionから進めます。

Conformを使うと、 z.object() によって生成されるZodのスキーマ定義に従ってバリデーションされます。
そのため、 parseWithZod() を使うだけで、バリデーションができます。

さらに、その戻り値を使い、 submission.reply() を返すことで、バリデーション結果をレスポンスすることができます。
このバリデーション結果は、あとで登場する、コンポーネント用のhook useForm に渡すことで、クライアント側でもエラー内容を取り扱うことができます。

最後に、コンポーネント側のコードです。

actionDataとloaderDataをもらうところまでは同じですね。

その後、 useForm というConformのフックを使います。このhookを使うと、次のことができるようになります。

  • クライアントサイドでのフォームバリデーション
  • サーバサイドバリデーションの結果をパース

先ほどとは異なり、バリデーションエラーは fields.name.errors のように、項目ごとに取得できるようになるので、項目ごとのヘルパーテキストとして表示するようにしてみました。

また、Formコンポーネントに {...getFormProps(form)} を渡すことで、フォーム送信前にクライアント側でのバリデーションが効くようになります。今回は、形式チェックのみなので、クライアントのバリデーションのみで引っかかってくれるのですが、この関数を外すことで、サーバサイドのバリデーションが効いていることを確認することができます。

さいごに

ConformはZodとRemixをうまく連携してくれることが分かりました。それ故に隠蔽された部分も感じられたのですが、それ以上にバリデーションのコードが短くなることが嬉しかったので、これは実践でも使ってみて良いかなと思いました。

おすすめ書籍

Reactハンズオンラーニング 第2版 ―Webアプリケーション開発のベストプラクティス プログラミングTypeScript ―スケールするJavaScriptアプリケーション開発

blog-page_footer_336




blog-page_footer_336




-FrontEnd

執筆者:

免責事項

このブログは、記事上部に記載のある投稿日時点の一般的な情報を提供するものであり、投資等の勧誘・法的・税務上の助言を提供するものではありません。仮想通貨の投資・損益計算は複雑であり、個々の取引状況や法律の変更によって異なる可能性があります。ブログに記載された情報は参考程度のものであり、特定の状況に基づいた行動の決定には専門家の助言を求めることをお勧めします。当ブログの情報に基づいた行動に関連して生じた損失やリスクについて、筆者は責任を負いかねます。最新の法律や税務情報を確認し、必要に応じて専門家に相談することをお勧めします。


comment

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA


関連記事

Go言語

Go WebAssemblyでPromiseを使って非同期化してみた

1 はじめに2 Go WebAssemblyで非同期化のコード3 Promise化する4 おまけ5 さいごに6 おすすめ書籍 はじめに 先日WebAssemblyに入門して、実際に以下のチュートリアル ...

Vue.js入門その3〜簡単にTODOアプリを作ってみたよ〜

はじめに 7/12 修正 記事下部にて、filterメソッドを使用している箇所がありましたが、forEachの方が適しているとご指摘がありましたので、修正しました。 以前Qiitaの方に投稿した記事で ...

Vue.js入門その1〜基本文法〜

はじめに 軽量JSフレームワークとして有名なVue.js。 最近、Laravelに触れる機会が増えたことと、以前からRails + Vueという構築を耳にするので、今更ではありますが勉強を始めようと思 ...

js

Reactを始める前に知っておきたいES2015/ES6の機能

1 はじめに2 ECMAScript – ES2015/ES6とは3 変数と定数とスコープ4 テンプレート文字列5 分割代入6 デフォルト引数7 残余引数(レストパラメータ)8 展開(スプ ...

svelte

Svelteのチュートリアルをやってみた

1 はじめに2 Svelteとは?2.1 Svelteの特徴2.2 Write less code2.3 No Virtual DOM2.4 Truly reactive3 Svelteのシンタックス ...

フォロー

blog-page_side_responsive

2024年10月
 12345
6789101112
13141516171819
20212223242526
2728293031  

アプリ情報

私たちは無料アプリもリリースしています、ぜひご覧ください。 下記のアイコンから無料でダウンロードできます。