Next.js預(yù)期錯(cuò)誤與未捕獲異常的處理方法
一、錯(cuò)誤的分類
錯(cuò)誤可以分為兩類:預(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ò)誤,這類錯(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> ) }
重要提示
- 上述示例中使用的
useFormState
hook 已包含在 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-11Javascript實(shí)現(xiàn)表單檢驗(yàn)
這篇文章主要介紹了Javascript實(shí)現(xiàn)表單檢驗(yàn),以注冊(cè)界面為例,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06JS實(shí)現(xiàn)保留n位小數(shù)的四舍五入問(wèn)題示例
這篇文章主要介紹了JS實(shí)現(xiàn)保留n位小數(shù)的四舍五入問(wèn)題,結(jié)合完整實(shí)例形式分析了javascript針對(duì)小數(shù)四舍五入操作技巧,需要的朋友可以參考下2016-08-08JS高級(jí)拖動(dòng)技術(shù) setCapture,releaseCapture
setCapture 的意思就是設(shè)置一個(gè)對(duì)象的方法被觸發(fā)的范圍,或者作用域。2011-07-07