Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Conform を推す - Advocating for Conform

Conform を推す - Advocating for Conform

### 発表者情報
- 溝口浩二 (@techtalkjp): https://x.com/techtalkjp

### Conform 関連リンク
- 公式サイト (日本語): https://ja.conform.guide/
- GitHub: https://github.com/edmundhung/conform
- 作者Edmund のBsky: https://bsky.app/profile/edmundhung.bsky.social

### デモ
- Next.js 15 app router での React Hook Form / Conform の様々な書き方デモ: https://form-validate-beige.vercel.app/

This presentation introduces Conform, a new form validation library designed to align with Web Standards and React's evolution. Comparing it with existing form libraries like React Hook Form, the talk explores Conform's key features including:
- Clean JSX code
- Built-in accessibility support
- Seamless integration with React 19 Server Functions
- Progressive enhancement capabilities
Learn how Conform brings together the best of Web Standards while leveraging modern React features, potentially representing the next generation of form libraries.

Web標準とReactの進化に合わせて設計された新しいフォームバリデーションライブラリ「Conform」についての紹介プレゼンテーションです。React Hook Formなど既存のフォームライブラリと比較しながら、Conformの特徴である:
- シンプルなJSXコード
- アクセシビリティへの対応
- React 19 Server Functionsとの自然な連携
- プログレッシブエンハンスメント
などについて解説しています。Web標準に立ち返りながらもモダンなReactの機能を活用できる、次世代のフォームライブラリの可能性を探ります。

Coji Mizoguchi

February 04, 2025
Tweet

More Decks by Coji Mizoguchi

Other Decks in Programming

Transcript

  1. 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 ( <form {...getFormProps(form)}> <input {...getInputProps(fields.email, { type: 'email' })} /> </form> ); }
  2. 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" /> <!-- エラー詳細要素のID --> <p id=":r2:-email-error">Required</p> <!-- エラー詳細 --> <form id=":r2:" novalidate> <label for=":r2:-email">Email</label> <input id=":r2:-email" form=":r2:" type="email" name="email" </form>
  3. 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 ( <form {...getFormProps(form)} action={action}> <input {...getInputProps(fields.email, { type: 'email' })} /> </form> ); }
  4. 4. プログレッシブエンハンスメント ページロード中など JS 無効状態でも動く。 サーバ側でバリデーションするだけでもバリデーション結果表示。 時間がないときに最低限の実装で、次の機能に進める。 時間ができたらクライアントサイドをリッチに。 RHF: クライアントサイドJSに依存。ちゃんと全部書く必要あり。

    import { myAction } from './action'; function MyForm() { const [lastResult, action] = useActionState(myAction, null) const [form, fields] = useForm({ // onValidate を設定しない = クライアントサイドでは検証せず。 lastResult // lastResult でサーバからの検証結果をフォームに反映 }); return ( <form action={action} {...getFormProps(form)}> <input {...getInputProps(fields.email, { type: 'email' })} /> </form> ); }
  5. 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 ( <form {...getFormProps(form)}> <input {...getInputProps(fields.email)} /> </form> ); }
  6. おまけ 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