Form Component
<Form> コンポーネントは、HTML の <form> 要素を拡張して、プリフェッチ、ローディング UI、 送信時のクライアントサイドナビゲーション、およびプログレッシブエンハンスメントを提供します。
URL の検索パラメータを更新するフォームに便利です。これにより、上記を実現するために必要な定型コードが削減されます。
基本的な使い方
import Form from 'next/form'
export default function Page() {
return (
<Form action="/search">
{/* On submission, the input value will be appended to
the URL, e.g. /search?query=abc */}
<input name="query" />
<button type="submit">Submit</button>
</Form>
)
}リファレンス
<Form> コンポーネントの動作は、action プロパティに string または function が渡されるかによって異なります。
actionが **string** の場合、<Form>はネイティブ HTML フォームのように動作し、**GET** メソッドを使用します。フォームデータは URL に検索パラメータとしてエンコードされ、フォームが送信されると指定された URL にナビゲートします。さらに、Next.js は- プリフェッチ フォームが表示されると、共有 UI (例:
layout.jsおよびloading.js) がプリロードされ、ナビゲーションが高速化されます。 - フォームが送信されると、ページ全体のリロードではなく、クライアントサイドナビゲーション を実行します。これにより、共有 UI とクライアントサイドの状態が維持されます。
- プリフェッチ フォームが表示されると、共有 UI (例:
actionが **function** (Server Action) の場合、<Form>は React フォーム のように動作し、フォームが送信されるとアクションを実行します。
action (string) プロパティ
action が string の場合、<Form> コンポーネントは以下のプロパティをサポートします。
| プロパティ | 例 | タイプ | 必須 |
|---|---|---|---|
action | action="/search" | string (URL または相対パス) | はい |
replace | replace={false} | boolean | - |
scroll | scroll={true} | boolean | - |
prefetch | prefetch={true} | boolean | - |
action: フォーム送信時にナビゲートする URL またはパス。- 空文字列
""は、検索パラメータを更新して同じルートにナビゲートします。
- 空文字列
replace: 新しい履歴エントリをプッシュするのではなく、現在の履歴状態を置き換えます。デフォルトはfalseです。scroll: ナビゲーション中のスクロール動作を制御します。デフォルトはtrueで、新しいルートの先頭にスクロールし、戻る/進むナビゲーションのスクロール位置を維持します。prefetch: フォームがユーザーのビューポートに表示されるときにパスがプリフェッチされるかどうかを制御します。デフォルトはtrueです。
action (function) プロパティ
action が function の場合、<Form> コンポーネントは以下のプロパティをサポートします。
| プロパティ | 例 | タイプ | 必須 |
|---|---|---|---|
action | action={myAction} | function (Server Action) | はい |
action: フォーム送信時に呼び出される Server Action。詳細については、React ドキュメント を参照してください。
知っておくと良いこと:
actionが function の場合、replaceおよびscrollプロパティは無視されます。
注意点
formAction:actionプロパティをオーバーライドするために<button>または<input type="submit">フィールドで使用できます。Next.js はクライアントサイドナビゲーションを実行しますが、このアプローチではプリフェッチはサポートされません。basePathを使用する場合、formActionパスにも含める必要があります。例:formAction="/base-path/search"。
key: 文字列actionにkeyプロパティを渡すことはサポートされていません。再レンダリングをトリガーしたり、ミューテーションを実行したりしたい場合は、代わりに functionactionの使用を検討してください。
onSubmit: フォーム送信ロジックを処理するために使用できます。ただし、event.preventDefault()を呼び出すと、指定された URL へのナビゲーションなどの<Form>の動作がオーバーライドされます。method,encType,target:<Form>の動作をオーバーライドするため、サポートされていません。- 同様に、
formMethod、formEncType、formTargetは、それぞれmethod、encType、targetプロパティをオーバーライドするために使用でき、それらを使用するとネイティブブラウザの動作にフォールバックします。 - これらのプロパティを使用する必要がある場合は、代わりに HTML の
<form>要素を使用してください。
- 同様に、
<input type="file">:actionが string の場合にこの入力タイプを使用すると、ファイルオブジェクトではなくファイル名を送信することにより、ブラウザの動作と一致します。
例
検索結果ページに遷移する検索フォーム
パスを action として渡すことで、検索結果ページにナビゲートする検索フォームを作成できます。
import Form from 'next/form'
export default function Page() {
return (
<Form action="/search">
<input name="query" />
<button type="submit">Submit</button>
</Form>
)
}ユーザーがクエリ入力フィールドを更新してフォームを送信すると、フォームデータは URL に検索パラメータとしてエンコードされます。例: /search?query=abc。
知っておくと良いこと:
actionに空文字列""を渡すと、フォームは検索パラメータを更新して同じルートにナビゲートします。
結果ページでは、page.js の searchParams プロパティを使用してクエリにアクセスし、外部ソースからデータを取得するために使用できます。
import { getSearchResults } from '@/lib/search'
export default async function SearchPage({
searchParams,
}: {
searchParams: Promise<{ [key: string]: string | string[] | undefined }>
}) {
const results = await getSearchResults((await searchParams).query)
return <div>...</div>
}<Form> がユーザーのビューポートに表示されると、/search ページの共有 UI (layout.js や loading.js など) がプリフェッチされます。送信時には、フォームはすぐに新しいルートにナビゲートし、結果が取得される間、ローディング UI を表示します。フォールバック UI は loading.js を使用して設計できます。
export default function Loading() {
return <div>Loading...</div>
}共有 UI がまだロードされていないケースに対応するために、useFormStatus を使用して、ユーザーに即座にフィードバックを表示できます。
まず、フォームが保留中の場合にローディング状態を表示するコンポーネントを作成します。
'use client'
import { useFormStatus } from 'react-dom'
export default function SearchButton() {
const status = useFormStatus()
return (
<button type="submit">{status.pending ? 'Searching...' : 'Search'}</button>
)
}次に、検索フォームページを更新して SearchButton コンポーネントを使用します。
import Form from 'next/form'
import { SearchButton } from '@/ui/search-button'
export default function Page() {
return (
<Form action="/search">
<input name="query" />
<SearchButton />
</Form>
)
}Server Actions を使用したミューテーション
action プロパティに関数を渡すことで、ミューテーションを実行できます。
import Form from 'next/form'
import { createPost } from '@/posts/actions'
export default function Page() {
return (
<Form action={createPost}>
<input name="title" />
{/* ... */}
<button type="submit">Create Post</button>
</Form>
)
}ミューテーション後、新しいリソースにリダイレクトするのが一般的です。next/navigation から redirect 関数を使用して、新しい投稿ページにナビゲートできます。
知っておくと良いこと: フォーム送信の「宛先」はアクションが実行されるまで不明なため、
<Form>は共有 UI を自動的にプリフェッチできません。
'use server'
import { redirect } from 'next/navigation'
export async function createPost(formData: FormData) {
// Create a new post
// ...
// Redirect to the new post
redirect(`/posts/${data.id}`)
}その後、新しいページで params プロパティを使用してデータを取得できます。
import { getPost } from '@/posts/data'
export default async function PostPage({
params,
}: {
params: Promise<{ id: string }>
}) {
const { id } = await params
const data = await getPost(id)
return (
<div>
<h1>{data.title}</h1>
{/* ... */}
</div>
)
}他の例については、Server Actions のドキュメントを参照してください。
役に立ちましたか?