一个 error 文件允许您处理意外的运行时错误并显示备用 UI。

"use client"; // Error boundaries must be Client Components
import { useEffect } from "react";
export default function Error({
error,
reset,
}: {
error: Error & { digest?: string };
reset: () => void;
}) {
useEffect(() => {
// Log the error to an error reporting service
console.error(error);
}, [error]);
return (
<div>
<h2>Something went wrong!</h2>
<button
onClick={
// Attempt to recover by trying to re-render the segment
() => reset()
}
>
Try again
</button>
</div>
);
}"use client"; // Error boundaries must be Client Components
import { useEffect } from "react";
export default function Error({ error, reset }) {
useEffect(() => {
// Log the error to an error reporting service
console.error(error);
}, [error]);
return (
<div>
<h2>Something went wrong!</h2>
<button
onClick={
// Attempt to recover by trying to re-render the segment
() => reset()
}
>
Try again
</button>
</div>
);
}error.js 将路由段及其嵌套子项包装在 React 错误边界 中。当边界内抛出错误时,error 组件将显示为备用 UI。

须知:
- React DevTools 允许您切换错误边界以测试错误状态。
- 如果您希望错误冒泡到父级错误边界,您可以在渲染
error组件时throw。
error一个 Error 对象的实例,转发到 error.js 客户端组件。
须知: 在开发过程中,转发到客户端的
Error对象将被序列化,并包含原始错误的message以便调试。然而,在生产环境中此行为有所不同,以避免将错误中可能包含的敏感详细信息泄露给客户端。
error.messageError 消息。errors.digest 下的标识符来匹配相应的服务器端日志。error.digest抛出错误的自动生成哈希值。它可用于匹配服务器端日志中的相应错误。
reset错误的原因有时可能是暂时的。在这种情况下,重试可能会解决问题。
错误组件可以使用 reset() 函数来提示用户尝试从错误中恢复。执行后,该函数将尝试重新渲染错误边界的内容。如果成功,备用错误组件将被重新渲染的结果替换。
"use client"; // Error boundaries must be Client Components
export default function Error({
error,
reset,
}: {
error: Error & { digest?: string };
reset: () => void;
}) {
return (
<div>
<h2>Something went wrong!</h2>
<button onClick={() => reset()}>Try again</button>
</div>
);
}"use client"; // Error boundaries must be Client Components
export default function Error({ error, reset }) {
return (
<div>
<h2>Something went wrong!</h2>
<button onClick={() => reset()}>Try again</button>
</div>
);
}虽然不常见,但您可以使用位于根 app 目录中的 global-error.jsx 来处理根布局或模板中的错误,即使在使用 国际化 时也是如此。全局错误 UI 必须定义其自己的 <html> 和 <body> 标签、全局样式、字体或错误页面所需的其他依赖项。此文件在激活时会替换根布局或模板。
须知:错误边界必须是 客户端组件,这意味着
global-error.jsx中不支持metadata和generateMetadata导出。作为替代方案,您可以使用 React<title>组件。
"use client"; // Error boundaries must be Client Components
export default function GlobalError({
error,
reset,
}: {
error: Error & { digest?: string };
reset: () => void;
}) {
return (
// global-error must include html and body tags
<html>
<body>
<h2>Something went wrong!</h2>
<button onClick={() => reset()}>Try again</button>
</body>
</html>
);
}"use client"; // Error boundaries must be Client Components
export default function GlobalError({ error, reset }) {
return (
// global-error must include html and body tags
<html>
<body>
<h2>Something went wrong!</h2>
<button onClick={() => reset()}>Try again</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 | null>;
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) {
// Render the current HTML content without hydration
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">
An error occurred during page rendering
</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) {
// Render the current HTML content without hydration
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">
An error occurred during page rendering
</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。 |