🐙
Next.js server actionsについて
server actionsとは
サーバー上で実行される非同期関数
使い方
'use server'をページの上につける
client componentでserve actionを呼ぶときには、'use server'を一番上に記述したファイルから呼び出す。
具体例
formで考えてみる。actionを実行すると、自動的にFormDataオブジェクトを呼ぶ。formに備わっている機能。
export default function Page(){
async function createInvoice(formData:FormData){
'use server'
const rawFormData={
customreId:formData.get('customeId'),
amount:formData.get('amount'),
status:formData.get('status'),
}
}
return <form action={createInvoice}>...</form>
}
ReactのuseFormStatusを使えばpending中かどうかがわかる
'use client'
import {useFormStatus} from'react-dom'
export function SubmitButton(){
const{pending}=useFormStatus()
return(
<button type"submit" disabled={pending}>Add</button>
)
}
sever componets
export default async function Home(){
return (
<form action={createItem}>
<input type ="text name="field-name"/>
<SubmitButton/>
</form>
)
}
formのvalidationチェックにzod(型定義を厳格にした)というlibraryを使ってみる
'use server'
const schema=z.object({
email:z.string({
invalid_type_error:'Invalid Email'
})
})
export default async function createUser(formData:FormData){
const validatedFields=schema.safeParse({
email:formData.get('email'),
})
if(!validatedFields.success){
return{
errors:validateFields.erro.flatten().fieldErrors,
}
}
}
server actionでのエラーの対応は、try/catch文で行う
'use server'
export async function createTodo(prevState:any,formData:FormData){
try{
}catch(e){
throw new Error('Failed to create task')
}
}
server action内でキャッシュを再検証するには、revalidatePath をしようする
'use server'
import {revalidatePath} from 'next/cache'
export async function createTodo(prevState:any,formData:FormData){
try{
}catch(e){
throw new Error('Failed to create task')
}
revalidatePath('/posts')
}
あるserve actionが終わった後にユーザーを別のページに移動させるためには、redirectを使う
redirectはtry/catch文の外側で使う
'use server'
import {revalidatePath} from 'next/cache'
export async function createTodo(prevState:any,formData:FormData){
try{
}catch(e){
throw new Error('Failed to create task')
}
revalidateTag('posts')// cacheされたpostsをアップデートする
redirect(`/post/${id}`)
}
server actionの中ではcookies APIが使える
'use server'
import {cookies} from 'next/headers'
export async function exampleAction(){
const value =cookies().get('name')?.value //get cookie
cookies().set('name','Delba') //set cookie
cookies().delete('name') //delite cookie
}
Discussion