Next.js預(yù)期錯(cuò)誤與未捕獲異常的處理方法
一、錯(cuò)誤的分類(lèi)
錯(cuò)誤可以分為兩類(lèi):預(yù)期錯(cuò)誤和未捕獲的異常。
- 預(yù)期錯(cuò)誤:在應(yīng)用程序正常運(yùn)行過(guò)程中可能會(huì)遇到的錯(cuò)誤,例如用戶輸入的錯(cuò)誤數(shù)據(jù)或請(qǐng)求失敗。
- 未捕獲的異常:程序中的意外錯(cuò)誤,通常表示代碼中存在 bug 或其他不應(yīng)出現(xiàn)的異常。
二、處理預(yù)期錯(cuò)誤
預(yù)期錯(cuò)誤是可以預(yù)見(jiàn)的錯(cuò)誤,這類(lèi)錯(cuò)誤應(yīng)該被明確處理,而不是讓它們未捕獲或拋出異常。常見(jiàn)的預(yù)期錯(cuò)誤場(chǎng)景包括服務(wù)端驗(yàn)證錯(cuò)誤或請(qǐng)求失敗等。
1. 處理來(lái)自 Server Actions 的預(yù)期錯(cuò)誤
當(dāng)在 Server Actions 中發(fā)生預(yù)期錯(cuò)誤時(shí),建議使用 useFormState hook 來(lái)管理這些錯(cuò)誤并返回給客戶端,而不是通過(guò) try/catch 語(yǔ)句塊來(lái)捕獲它們。
示例:創(chuàng)建用戶時(shí)處理錯(cuò)誤
// app/actions.js
'use server'
import { redirect } from 'next/navigation'
export async function createUser(prevState, formData) {
const res = await fetch('https://...')
const json = await res.json()
if (!res.ok) {
return { message: '請(qǐng)輸入有效的郵箱' }
}
redirect('/dashboard')
}
在這個(gè)例子中,如果請(qǐng)求失敗,createUser 將返回一個(gè)錯(cuò)誤消息,而不是拋出異常。
然后,在客戶端組件中,可以通過(guò) useFormState 來(lái)處理返回的狀態(tài),展示錯(cuò)誤消息。
// app/ui/signup.js
'use client'
import { useFormState } from 'react'
import { createUser } from '@/app/actions'
const initialState = {
message: '',
}
export function Signup() {
const [state, formAction] = useFormState(createUser, initialState)
return (
<form action={formAction}>
<label htmlFor="email">郵箱</label>
<input type="text" id="email" name="email" required />
<p aria-live="polite">{state?.message}</p>
<button>注冊(cè)</button>
</form>
)
}
重要提示
- 上述示例中使用的
useFormStatehook 已包含在 Next.js App Router 中。如果使用的是 React 19,請(qǐng)使用useActionState。 useFormState提供的state可用于在客戶端組件中顯示錯(cuò)誤消息,提升用戶體驗(yàn)。
2. 處理來(lái)自 Server Components 的預(yù)期錯(cuò)誤
在 Server Component 中獲取數(shù)據(jù)時(shí),可以根據(jù)請(qǐng)求的響應(yīng)結(jié)果決定是否渲染錯(cuò)誤消息或進(jìn)行頁(yè)面重定向。
// app/page.js
export default async function Page() {
const res = await fetch(`https://...`)
const data = await res.json()
if (!res.ok) {
return '發(fā)生了錯(cuò)誤。'
}
return '...'
}
三、處理未捕獲的異常
未捕獲的異常是指程序中不應(yīng)發(fā)生的錯(cuò)誤,通常表明存在 bug。對(duì)于這些異常,我們應(yīng)使用錯(cuò)誤邊界進(jìn)行捕獲并提供備用 UI。
1. 使用錯(cuò)誤邊界
錯(cuò)誤邊界允許我們捕獲子組件中的異常,并顯示一個(gè)備用的 UI,而不是讓整個(gè)組件樹(shù)崩潰。
在 Next.js 中,可以通過(guò)在路由段中添加 error.tsx 文件來(lái)創(chuàng)建錯(cuò)誤邊界。
// app/dashboard/error.js
'use client'
import { useEffect } from 'react'
export default function Error({ error, reset }) {
useEffect(() => {
// 將錯(cuò)誤記錄到錯(cuò)誤報(bào)告服務(wù)
console.error(error)
}, [error])
return (
<div>
<h2>出現(xiàn)了問(wèn)題!</h2>
<button onClick={reset}>重試</button>
</div>
)
}
錯(cuò)誤冒泡
如果希望錯(cuò)誤冒泡到父級(jí)錯(cuò)誤邊界,可以在渲染 Error 組件時(shí)使用 throw 拋出錯(cuò)誤。
2. 處理嵌套路由中的錯(cuò)誤
錯(cuò)誤會(huì)冒泡到最近的父級(jí)錯(cuò)誤邊界。因此,可以在不同級(jí)別的路由段中放置 error.tsx 文件,以實(shí)現(xiàn)更細(xì)粒度的錯(cuò)誤處理。
// app/dashboard/error.js // 錯(cuò)誤邊界組件
四、處理全局錯(cuò)誤
雖然不常見(jiàn),但我們可以使用位于根 app 目錄中的 app/global-error.js 來(lái)處理根布局中的錯(cuò)誤,確保即使在國(guó)際化場(chǎng)景下也能正常處理錯(cuò)誤。
示例:處理全局錯(cuò)誤
// app/global-error.js
'use client'
export default function GlobalError({ error, reset }) {
return (
<html>
<body>
<h2>出現(xiàn)了問(wèn)題!</h2>
<button onClick={() => reset()}>重試</button>
</body>
</html>
)
}
重要提示
- 全局錯(cuò)誤 UI 必須包含
<html>和<body>標(biāo)簽,因?yàn)樗鼤?huì)在激活時(shí)替換根布局或模板。 global-error.js文件提供了全局錯(cuò)誤處理的能力,確保在整個(gè)應(yīng)用中能夠優(yōu)雅地處理未捕獲的異常。
到此這篇關(guān)于Next.js預(yù)期錯(cuò)誤與未捕獲異常的處理方法的文章就介紹到這了,更多相關(guān)Next.js預(yù)期錯(cuò)誤與未捕獲異常內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
元素全屏的設(shè)置與監(jiān)聽(tīng)實(shí)例
下面小編就為大家?guī)?lái)一篇元素全屏的設(shè)置與監(jiān)聽(tīng)實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2017-11-11
Javascript實(shí)現(xiàn)表單檢驗(yàn)
這篇文章主要介紹了Javascript實(shí)現(xiàn)表單檢驗(yàn),以注冊(cè)界面為例,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06
JS實(shí)現(xiàn)保留n位小數(shù)的四舍五入問(wèn)題示例
這篇文章主要介紹了JS實(shí)現(xiàn)保留n位小數(shù)的四舍五入問(wèn)題,結(jié)合完整實(shí)例形式分析了javascript針對(duì)小數(shù)四舍五入操作技巧,需要的朋友可以參考下2016-08-08
JS高級(jí)拖動(dòng)技術(shù) setCapture,releaseCapture
setCapture 的意思就是設(shè)置一個(gè)對(duì)象的方法被觸發(fā)的范圍,或者作用域。2011-07-07

