error.js
error 檔案讓您能處理意外的執行時錯誤並顯示後備 UI。

'use client' // 錯誤邊界必須是客戶端元件
import { useEffect } from 'react'
export default function Error({
error,
reset,
}: {
error: Error & { digest?: string }
reset: () => void
}) {
useEffect(() => {
// 將錯誤記錄到錯誤報告服務
console.error(error)
}, [error])
return (
<div>
<h2>發生錯誤!</h2>
<button
onClick={
// 嘗試重新渲染該區段來恢復
() => reset()
}
>
重試
</button>
</div>
)
}
'use client' // 錯誤邊界必須是客戶端元件
import { useEffect } from 'react'
export default function Error({ error, reset }) {
useEffect(() => {
// 將錯誤記錄到錯誤報告服務
console.error(error)
}, [error])
return (
<div>
<h2>發生錯誤!</h2>
<button
onClick={
// 嘗試重新渲染該區段來恢復
() => reset()
}
>
重試
</button>
</div>
)
}
error.js
將路由區段及其嵌套子元件包裹在 React 錯誤邊界中。當邊界內發生錯誤時,error
元件會顯示為後備 UI。

須知事項:
- React DevTools 可讓您切換錯誤邊界來測試錯誤狀態
- 若希望錯誤冒泡到父級錯誤邊界,可在渲染
error
元件時使用throw
參考
屬性
error
傳遞給 error.js
客戶端元件的 Error
物件實例。
須知事項: 在開發環境中,傳遞給客戶端的
Error
物件會被序列化並包含原始錯誤的message
以便除錯。但在生產環境中行為不同,以避免將錯誤中可能包含的敏感細節洩漏給客戶端。
error.message
- 從客戶端元件傳遞的錯誤會顯示原始
Error
訊息 - 從伺服器元件傳遞的錯誤會顯示帶有識別碼的通用訊息。這是為了防止洩漏敏感細節。您可以使用
errors.digest
下的識別碼來匹配對應的伺服器端日誌
error.digest
自動生成的錯誤拋出雜湊值。可用於匹配伺服器端日誌中的對應錯誤。
reset
有時錯誤原因可能是暫時性的。在這些情況下,重試可能解決問題。
錯誤元件可以使用 reset()
函數提示使用者嘗試從錯誤中恢復。執行時,該函數會嘗試重新渲染錯誤邊界的內容。若成功,後備錯誤元件將被重新渲染的結果取代。
'use client' // 錯誤邊界必須是客戶端元件
export default function Error({
error,
reset,
}: {
error: Error & { digest?: string }
reset: () => void
}) {
return (
<div>
<h2>發生錯誤!</h2>
<button onClick={() => reset()}>重試</button>
</div>
)
}
'use client' // 錯誤邊界必須是客戶端元件
export default function Error({ error, reset }) {
return (
<div>
<h2>發生錯誤!</h2>
<button onClick={() => reset()}>重試</button>
</div>
)
}
範例
全域錯誤
雖然較不常見,但您可以使用位於根應用目錄中的 global-error.js
來處理根佈局或模板中的錯誤,即使在啟用國際化時也是如此。全域錯誤 UI 必須定義自己的 <html>
和 <body>
標籤。此檔案在啟用時會取代根佈局或模板。
'use client' // 錯誤邊界必須是客戶端元件
export default function GlobalError({
error,
reset,
}: {
error: Error & { digest?: string }
reset: () => void
}) {
return (
// global-error 必須包含 html 和 body 標籤
<html>
<body>
<h2>發生錯誤!</h2>
<button onClick={() => reset()}>重試</button>
</body>
</html>
)
}
'use client' // 錯誤邊界必須是客戶端元件
export default function GlobalError({ error, reset }) {
return (
// global-error 必須包含 html 和 body 標籤
<html>
<body>
<h2>發生錯誤!</h2>
<button onClick={() => reset()}>重試</button>
</body>
</html>
)
}
使用自訂錯誤邊界優雅恢復
當客戶端渲染失敗時,顯示最後已知的伺服器渲染 UI 可以提供更好的使用者體驗。
GracefullyDegradingErrorBoundary
是一個自訂錯誤邊界範例,它會捕捉並保留錯誤發生前的當前 HTML。如果發生渲染錯誤,它會重新渲染捕捉到的 HTML 並顯示持續通知欄來告知使用者。
'use client'
import React, { Component, ErrorInfo, ReactNode } from 'react'
interface ErrorBoundaryProps {
children: ReactNode
onError?: (error: Error, errorInfo: ErrorInfo) => void
}
interface ErrorBoundaryState {
hasError: boolean
}
export class GracefullyDegradingErrorBoundary extends Component<
ErrorBoundaryProps,
ErrorBoundaryState
> {
private contentRef: React.RefObject<HTMLDivElement>
constructor(props: ErrorBoundaryProps) {
super(props)
this.state = { hasError: false }
this.contentRef = React.createRef()
}
static getDerivedStateFromError(_: Error): ErrorBoundaryState {
return { hasError: true }
}
componentDidCatch(error: Error, errorInfo: ErrorInfo) {
if (this.props.onError) {
this.props.onError(error, errorInfo)
}
}
render() {
if (this.state.hasError) {
// 渲染當前 HTML 內容而不進行水合
return (
<>
<div
ref={this.contentRef}
suppressHydrationWarning
dangerouslySetInnerHTML={{
__html: this.contentRef.current?.innerHTML || '',
}}
/>
<div className="fixed bottom-0 left-0 right-0 bg-red-600 text-white py-4 px-6 text-center">
<p className="font-semibold">
頁面渲染期間發生錯誤
</p>
</div>
</>
)
}
return <div ref={this.contentRef}>{this.props.children}</div>
}
}
export default GracefullyDegradingErrorBoundary
'use client'
import React, { Component, createRef } from 'react'
class GracefullyDegradingErrorBoundary extends Component {
constructor(props) {
super(props)
this.state = { hasError: false }
this.contentRef = createRef()
}
static getDerivedStateFromError(_) {
return { hasError: true }
}
componentDidCatch(error, errorInfo) {
if (this.props.onError) {
this.props.onError(error, errorInfo)
}
}
render() {
if (this.state.hasError) {
// 渲染當前 HTML 內容而不進行水合
return (
<>
<div
ref={this.contentRef}
suppressHydrationWarning
dangerouslySetInnerHTML={{
__html: this.contentRef.current?.innerHTML || '',
}}
/>
<div className="fixed bottom-0 left-0 right-0 bg-red-600 text-white py-4 px-6 text-center">
<p className="font-semibold">
頁面渲染期間發生錯誤
</p>
</div>
</>
)
}
return <div ref={this.contentRef}>{this.props.children}</div>
}
}
export default GracefullyDegradingErrorBoundary
版本歷史
版本 | 變更內容 |
---|---|
v15.2.0 | 在開發環境中也顯示 global-error |
v13.1.0 | 引入 global-error |
v13.0.0 | 引入 error |