はじめに
next.jsのサーバーアクション内でリダイレクト関数を使用していたところ、リダイレクトできない症状に遭遇しました。
誤ったコード
try-catch文の中で直接redirect関数を記述しても、リダイレクトは効きません。
action.ts
'use server'
import { FormData } from '@/src/commons/types/type'
import { PrismaClient } from '@prisma/client'
import { redirect } from 'next/navigation'
const prisma = new PrismaClient()
export async function postFormAction(data: FormData) {
try {
const formData: FormData = {
// FormData から必要なプロパティを抽出する
}
const createdFormData = await prisma.FormData.create({
data: formData,
})
redirect('/')
} catch (error) {
console.error('Error creating FormData:', error)
throw error
}
}
理由
公式ドキュメントに対処法の記載がありました。
try-catch文の外にredirect関数は配置する必要があるようです。
redirect関数はリダイレクトが必要なことを示すエラーをスローするため、tryの中でリダイレクト関数を実行すると、catchの処理が実行されることになります。
修正したコード
以下のように、直接try文の中にリダイレクトを記述せず、外に逃がしてあげることで、正常にリダイレクトが実行できるようになりました。
action.ts
'use server'
import { FormData } from '@/src/commons/types/type'
import { PrismaClient } from '@prisma/client'
import { redirect } from 'next/navigation'
const prisma = new PrismaClient()
export async function postFormAction(data: FormData) {
let redirectRequired = false // リダイレクトするかの判定フラグ
try {
const formData: FormData = {
// FormData から必要なプロパティを抽出する
}
const createdFormData = await prisma.FormData.create({
data: formData,
})
redirectRequired = true
} catch (error) {
console.error('Error creating FormData:', error)
throw error
}
if (redirectRequired) {
redirect('/') // redirect関数をtry catch文の外で実行する
}
}
参考にした記事