Slide 1

Slide 1 text

Conform を推す 溝口浩二 @techtalkjp プログラマー 数人規模で作られてるめっちゃ便利なものが好き remix, conform, fly.io, duckdb, turso 推しです Web標準とReactの進化に寄り添うフォームバリデーション

Slide 2

Slide 2 text

フォームライブラリ、何使ってますか? React Hook Form (RHF) 使ってる人 🙋‍♂️ 柔軟で使いやすいですよね。 みんな使ってて安心ですね!(いまは) でも、ちょっとフォームやフィールドまわりのコードがゴチャつきません? 覚えること意外に多くないです? そしてそれを毎回忘れませんか? React 19 への対応、どうします…? そこで Conform を推す

Slide 3

Slide 3 text

Conformとは? Web標準のHTMLフォームを拡張するフォームライブラリ サーバーサイドとの連携を第一に設計。 フォーム周りのコードがシンプルに。 覚えやすい。忘れない。 以下、私が Conform の好きなところを、ご紹介していきます。

Slide 4

Slide 4 text

1. JSX がスッキリ Web標準に準拠したシンプルな記述 getFormProps , getInputProps で見通し◎ import { useForm, getFormProps, getInputProps } from '@conform-to/react'; import { parseWithZod } from '@conform-to/zod'; import { z } from 'zod'; const schema = z.object({ email: z.string().email(), }); function MyForm() { const [form, fields] = useForm({ onValidate: ({ formData }) => parseWithZod(formData, { schema }); }); return ( ); }

Slide 5

Slide 5 text

2. アクセシビリティ(a11y)にも対応 Web標準のフォーム要素: そもそも論として、セマンティックなHTMLはa11yの基本 ヘルパー関数: getFormProps , getInputProps などのヘルパー関数で、 aria-invalid , aria-describedby などの a17y 属性も自動で設定される。 ↑バリデーションエラー時にレンダリングされるHTML エラー表示要素に id 属性を設定 ( field.email.errorId ) それを示す aria-describedby 属性が input に自動で設定される コントロールに aria-invalid 属性が付与されるので、エラー時スタイリングでも使いやすい。 aria-invalid="true" aria-describedby=":r2:-email-error" />

Required

Email

Slide 6

Slide 6 text

3. サーバー連携が直感的 form の submit はサーバーに送信される、という基本に忠実 React 19 Server Functions に対応。極めて自然な連携。 React Hook Form: Server Functions には非対応。 'use server'; export const myAction = async (prevState, formData) => { const submission = parseWithZod(formData, { schema }); // formDataをparseして検証 if (submission.status !== 'success') { return submission.reply(); } // 検証成功後の処理 }; 'use client'; function MyForm() { const [lastResult, action] = useActionState(myAction, null) const [form, fields] = useForm({ lastResult }); return ( ); }

Slide 7

Slide 7 text

4. プログレッシブエンハンスメント ページロード中など JS 無効状態でも動く。 サーバ側でバリデーションするだけでもバリデーション結果表示。 時間がないときに最低限の実装で、次の機能に進める。 時間ができたらクライアントサイドをリッチに。 RHF: クライアントサイドJSに依存。ちゃんと全部書く必要あり。 import { myAction } from './action'; function MyForm() { const [lastResult, action] = useActionState(myAction, null) const [form, fields] = useForm({ // onValidate を設定しない = クライアントサイドでは検証せず。 lastResult // lastResult でサーバからの検証結果をフォームに反映 }); return ( ); }

Slide 8

Slide 8 text

5. Zod, Yup, Valibot を使ったバリデーション parseWithZod , parseWithYup , parseWithValibot で普通にできます。 import { z } from 'zod'; onValidate: ({ formData }) => parseWithZod(formData, { schema }); import { useForm, getInputProps } from '@conform-to/react'; import { parseWithZod } from '@conform-to/zod'; const schema = z.object({ email: z.string().email(), }); function MyForm() { const [form, fields] = useForm({ }); return ( ); }

Slide 9

Slide 9 text

まとめ Conform: Web標準に回帰し、Reactの進化に寄り添うフォームライブラリ JSX のシンプルさ、直感的なサーバー連携 React 19 の Server Functions にも対応 今こそ Conform を試してみませんか?

Slide 10

Slide 10 text

おまけ Next.js 15 app router での React Hook Form / Conform の様々な書き方デモ Next.js Form Validation Examples 1. React Hook Form - Old Style Fetch 2. React Hook Form - Old Style Server Actions 3. React Hook Form - Form Fetch 4. React Hook Form - Form Server Actions 5. Conform - Oldstyle Fetch 6. Conform - Server Actions 7. Conform - Dynamic

Slide 11

Slide 11 text

リソース 公式サイト (日本語): https://ja.conform.guide/ GitHub: https://github.com/edmundhung/conform Conform 作者 Edmund の bsky