Next.js预期错误与未捕获异常的处理方法

 更新时间:2025年03月12日 09:41:53   作者:Peter-Lu  
在开发过程中,错误是不可避免的,如何优雅地处理这些错误是提升应用稳定性与用户体验的关键,本文将详细介绍如何在 Next.js 中处理预期错误与未捕获的异常,包括使用 useFormState 处理预期错误,使用错误边界捕获未捕获的异常,需要的朋友可以参考下

一、错误的分类

错误可以分为两类:预期错误未捕获的异常

  • 预期错误:在应用程序正常运行过程中可能会遇到的错误,例如用户输入的错误数据或请求失败。
  • 未捕获的异常:程序中的意外错误,通常表示代码中存在 bug 或其他不应出现的异常。

二、处理预期错误

预期错误是可以预见的错误,这类错误应该被明确处理,而不是让它们未捕获或抛出异常。常见的预期错误场景包括服务端验证错误或请求失败等。

1. 处理来自 Server Actions 的预期错误

当在 Server Actions 中发生预期错误时,建议使用 useFormState hook 来管理这些错误并返回给客户端,而不是通过 try/catch 语句块来捕获它们。

示例:创建用户时处理错误

// 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: '请输入有效的邮箱' }
  }

  redirect('/dashboard')
}

在这个例子中,如果请求失败,createUser 将返回一个错误消息,而不是抛出异常。

然后,在客户端组件中,可以通过 useFormState 来处理返回的状态,展示错误消息。

// 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>注册</button>
    </form>
  )
}

重要提示

  • 上述示例中使用的 useFormState hook 已包含在 Next.js App Router 中。如果使用的是 React 19,请使用 useActionState
  • useFormState 提供的 state 可用于在客户端组件中显示错误消息,提升用户体验。

2. 处理来自 Server Components 的预期错误

在 Server Component 中获取数据时,可以根据请求的响应结果决定是否渲染错误消息或进行页面重定向。

// app/page.js
export default async function Page() {
  const res = await fetch(`https://...`)
  const data = await res.json()

  if (!res.ok) {
    return '发生了错误。'
  }

  return '...'
}

三、处理未捕获的异常

未捕获的异常是指程序中不应发生的错误,通常表明存在 bug。对于这些异常,我们应使用错误边界进行捕获并提供备用 UI。

1. 使用错误边界

错误边界允许我们捕获子组件中的异常,并显示一个备用的 UI,而不是让整个组件树崩溃。

在 Next.js 中,可以通过在路由段中添加 error.tsx 文件来创建错误边界。

// app/dashboard/error.js
'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 组件时使用 throw 抛出错误。

2. 处理嵌套路由中的错误

错误会冒泡到最近的父级错误边界。因此,可以在不同级别的路由段中放置 error.tsx 文件,以实现更细粒度的错误处理。

// app/dashboard/error.js
// 错误边界组件

四、处理全局错误

虽然不常见,但我们可以使用位于根 app 目录中的 app/global-error.js 来处理根布局中的错误,确保即使在国际化场景下也能正常处理错误。

示例:处理全局错误

// app/global-error.js
'use client'

export default function GlobalError({ error, reset }) {
  return (
    <html>
      <body>
        <h2>出现了问题!</h2>
        <button onClick={() => reset()}>重试</button>
      </body>
    </html>
  )
}

重要提示

  • 全局错误 UI 必须包含 <html> 和 <body> 标签,因为它会在激活时替换根布局或模板。
  • global-error.js 文件提供了全局错误处理的能力,确保在整个应用中能够优雅地处理未捕获的异常。

到此这篇关于Next.js预期错误与未捕获异常的处理方法的文章就介绍到这了,更多相关Next.js预期错误与未捕获异常内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • JS如何修改对象数组的key值

    JS如何修改对象数组的key值

    这篇文章主要介绍了JS如何修改对象数组的key值,使用map循环,在map循环内创建一个新对象,将item要改变的key赋给新创建的对象里面新key值,然后push给一个新创建的数组dataNew即可,需要的朋友可以参考下
    2024-02-02
  • 元素全屏的设置与监听实例

    元素全屏的设置与监听实例

    下面小编就为大家带来一篇元素全屏的设置与监听实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2017-11-11
  • Javascript实现表单检验

    Javascript实现表单检验

    这篇文章主要介绍了Javascript实现表单检验,以注册界面为例,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-06-06
  • 微信小程序实现拍照打卡功能

    微信小程序实现拍照打卡功能

    这篇文章主要为大家详细介绍了微信小程序实现拍照打卡功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • 如何调试异步加载页面里包含的js文件

    如何调试异步加载页面里包含的js文件

    用浏览器无法调试异步加载页面里包含的js文件。简单的说就是在调试工具里面看不到异步加载页面里包含的js文件
    2014-10-10
  • JavaScript 不只是脚本

    JavaScript 不只是脚本

    JavaScript 不只是脚本...
    2007-05-05
  • 拖动布局之保存布局页面cookies篇

    拖动布局之保存布局页面cookies篇

    拖动后怎么把布局结果保存呢??我开始考虑是记录每个拖动对象的的坐标,可做起来我感觉好麻烦,所以就没有采用这种方法。
    2010-10-10
  • JS实现保留n位小数的四舍五入问题示例

    JS实现保留n位小数的四舍五入问题示例

    这篇文章主要介绍了JS实现保留n位小数的四舍五入问题,结合完整实例形式分析了javascript针对小数四舍五入操作技巧,需要的朋友可以参考下
    2016-08-08
  • JS高级拖动技术 setCapture,releaseCapture

    JS高级拖动技术 setCapture,releaseCapture

    setCapture 的意思就是设置一个对象的方法被触发的范围,或者作用域。
    2011-07-07
  • Openlayers实现地图全屏显示

    Openlayers实现地图全屏显示

    这篇文章主要为大家详细介绍了Openlayers实现地图全屏显示,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-09-09

最新评论