You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NextJS 14(App Router)页面切换加载组件报错求助

解决Next.js 14 App Router中NextRouter未挂载的报错

错误原因

你在Next.js 14的App Router环境中使用了Pages Router专属的next/router包的useRouter,两者路由机制不兼容,导致路由实例未挂载时调用API抛出错误。Next.js 12用的是Pages Router,所以原代码能正常运行,但升级到14后切换到App Router(从app/layout.tsx的结构可判断),必须使用App Router对应的路由API。

解决方案

1. 替换路由API

把next/router替换为App Router专属的next/navigation包,这是App Router环境下获取路由实例的正确方式。

2. 调整路由加载状态监听逻辑

App Router的useRouter不再提供events对象用于监听路由变化,而是内置了isPending属性直接反映路由加载状态。结合该属性可简化加载组件逻辑,同时保留你原有的延迟隐藏效果。

修改后的Loading.tsx代码:

'use client'

import { useEffect, useState } from 'react'
import { useRouter } from 'next/navigation'

import styles from './Loading.module.scss'

const Loading = () => {
    const [loading, setLoading] = useState(false)
    const router = useRouter()

    useEffect(() => {
        let timer: NodeJS.Timeout

        if (router.isPending) {
            // 路由开始加载时显示加载组件
            setLoading(true)
        } else {
            // 路由加载完成后延迟1秒隐藏
            timer = setTimeout(() => setLoading(false), 1000)
        }

        return () => {
            if (timer) clearTimeout(timer)
        }
    }, [router.isPending])

    return loading && <div className={styles.loading} />
}

export default Loading

3. 验证RootLayout配置

你的app/layout.tsx配置无需修改,因为Loading组件已标记为'use client',可以在默认是服务器组件的RootLayout中正常渲染。

关键说明

  • App Router和Pages Router的路由API不兼容,迁移时要替换所有next/router相关的导入和用法。
  • router.isPending是App Router中专门用于判断路由是否处于加载状态的属性,比手动监听事件更简洁可靠。
  • 保留延迟隐藏逻辑是为了和你原有的用户体验保持一致,避免加载组件闪烁。

内容的提问来源于stack exchange,提问作者Alikhani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 16:40:09