データの更新方法
Next.jsでは、ReactのServer Functionsを使用してデータを更新できます。このページでは、Server Functionsの作成と呼び出し方法を説明します。
サーバー関数の作成
Server Functionはuse server
` ディレクティブを使用して定義できます。このディレクティブは、非同期関数の先頭に置いてその関数をServer Functionとしてマークするか、別のファイルの先頭に置いてそのファイルのすべてのエクスポートをマークするために使用できます。
export async function createPost(formData: FormData) {
'use server'
const title = formData.get('title')
const content = formData.get('content')
// Update data
// Revalidate cache
}
export async function deletePost(formData: FormData) {
'use server'
const id = formData.get('id')
// Update data
// Revalidate cache
}
サーバーコンポーネント
Server Componentsでは、関数本体の先頭に"use server"
ディレクティブを追加することで、Server Functionをインラインで定義できます
export default function Page() {
// Server Action
async function createPost(formData: FormData) {
'use server'
// ...
}
return <></>
}
クライアントコンポーネント
Client ComponentsでServer Functionを定義することはできません。ただし、ファイルの先頭に"use server"
ディレクティブが記述されているファイルからServer Functionをインポートすることで、Client ComponentsからServer Functionを呼び出すことができます
'use server'
export async function createPost() {}
'use client'
import { createPost } from '@/app/actions'
export function Button() {
return <button formAction={createPost}>Create</button>
}
サーバー関数の呼び出し
Server Functionを呼び出す主な方法は2つあります
フォーム
ReactはHTMLの<form>
要素を拡張し、HTMLのaction
プロパティでServer Functionを呼び出せるようにします。
フォームで呼び出されると、関数は自動的にFormData
オブジェクトを受け取ります。データはネイティブのFormData
メソッドを使用して抽出できます。
import { createPost } from '@/app/actions'
export function Form() {
return (
<form action={createPost}>
<input type="text" name="title" />
<input type="text" name="content" />
<button type="submit">Create</button>
</form>
)
}
'use server'
export async function createPost(formData: FormData) {
const title = formData.get('title')
const content = formData.get('content')
// Update data
// Revalidate cache
}
知っておくと便利:
action
プロパティに渡される場合、Server FunctionsはServer Actionsとしても知られています。
イベントハンドラ
Client Componentでは、onClick
などのイベントハンドラを使用してServer Functionを呼び出すことができます。
'use client'
import { incrementLike } from './actions'
import { useState } from 'react'
export default function LikeButton({ initialLikes }: { initialLikes: number }) {
const [likes, setLikes] = useState(initialLikes)
return (
<>
<p>Total Likes: {likes}</p>
<button
onClick={async () => {
const updatedLikes = await incrementLike()
setLikes(updatedLikes)
}}
>
Like
</button>
</>
)
}
例
保留状態の表示
Server Functionの実行中には、ReactのuseActionState
フックを使用してローディングインジケータを表示できます。このフックはpending
ブール値を返します
'use client'
import { useActionState } from 'react'
import { createPost } from '@/app/actions'
import { LoadingSpinner } from '@/app/ui/loading-spinner'
export function Button() {
const [state, action, pending] = useActionState(createPost, false)
return (
<button onClick={async () => action()}>
{pending ? <LoadingSpinner /> : 'Create Post'}
</button>
)
}
キャッシュの再検証
更新を実行した後、Server Function内でrevalidatePath
またはrevalidateTag
を呼び出すことで、Next.jsのキャッシュを再検証し、更新されたデータを表示できます
import { revalidatePath } from 'next/cache'
export async function createPost(formData: FormData) {
'use server'
// Update data
// ...
revalidatePath('/posts')
}
リダイレクト
更新を実行した後、ユーザーを別のページにリダイレクトしたい場合があります。これは、Server Function内でredirect
を呼び出すことで実現できます
'use server'
import { redirect } from 'next/navigation'
export async function createPost(formData: FormData) {
// Update data
// ...
redirect('/posts')
}
APIリファレンス
この情報は役立ちましたか?