
本文旨在解决 Next.js 13 中 loading.tsx 组件无法在页面刷新时显示的问题。通过分析 Next.js 的路由机制和 Loading UI 的工作原理,阐述了 Loading 组件的正确使用场景,并提供了一种在页面初次加载时模拟 Loading 效果的方案,帮助开发者提升用户体验。
理解 Next.js 13 的 Loading UI
在 Next.js 13 的 App Router 中,loading.tsx 文件用于创建 Loading UI。这个 Loading UI 的主要作用是在页面导航时,为用户提供即时的反馈,表明页面正在加载。它会在新页面组件完全渲染之前显示,从而提升用户体验。
关键在于,loading.tsx 是为页面导航设计的,而不是为页面首次加载设计的。当你直接访问或刷新一个页面时,Next.js 会直接渲染服务器返回的完整页面,而不会触发 Loading UI。
问题分析:为何 Loading 组件未显示?
根据提供的代码,loading.tsx 文件和 page.tsx 文件都放置在正确的目录下。但是,Loading 组件未显示的原因在于:页面是直接加载或刷新的,而非通过 Next.js 的路由进行导航。
Next.js 官方文档明确指出,Loading UI 的设计目的是为了在页面导航时提供即时反馈。因此,直接访问或刷新页面时,不会触发 Loading UI。
解决方案:模拟首次加载时的 Loading 效果
虽然 loading.tsx 不能直接用于页面首次加载,但我们可以通过其他方式模拟 Loading 效果。一种常见的做法是使用状态管理和条件渲染。
示例代码:
import { useState, useEffect } from 'react';
import { IResult } from '@/interface';
import Results from '@/components/Results';
const API_KEY = process.env.API_KEY;
export default function Home({ searchParams }: { searchParams: any }) {
const [isLoading, setIsLoading] = useState(true); // 初始状态为加载中
const [results, setResults] = useState([]);
const genre = searchParams.genre || 'fetchTrending';
useEffect(() => {
const fetchData = async () => {
try {
const res = await fetch(
`https://api.themoviedb.org/3/${
genre === 'fetchTopRated' ? 'movie/top_rated' : 'trending/all/week'
}?api_key=${API_KEY}&language=en-US&page=1`,
{ next: { revalidate: 100000 } }
);
if (!res.ok) {
throw new Error('Failed to fetch data');
}
const data = await res.json();
setResults(data.results as IResult[]);
} finally {
setIsLoading(false); // 加载完成后设置为 false
}
};
fetchData();
}, [genre]);
if (isLoading) {
return Loading...; // 显示 Loading 组件
}
return (
<>
>
);
} 代码解释:
- useState(true): 使用 useState hook 创建一个名为 isLoading 的状态变量,初始值为 true,表示页面正在加载。
- useEffect: 使用 useEffect hook 在组件挂载后执行数据获取操作。
- fetchData: 定义一个异步函数 fetchData,用于获取数据。
- setIsLoading(false): 在数据获取完成后,无论成功与否,都将 isLoading 设置为 false,表示加载完成。finally 块确保无论成功或失败,都会执行。
- 条件渲染: 使用条件渲染判断 isLoading 的值。如果为 true,则显示 Loading 组件;否则,显示实际的页面内容。
注意事项:
- 确保 loading.tsx 文件仍然存在,以便在页面导航时显示 Loading UI。
- 可以根据实际需求自定义 Loading 组件的样式和内容。
- 对于更复杂的场景,可以使用更高级的状态管理库(如 Redux 或 Zustand)来管理加载状态。
总结
Next.js 13 的 loading.tsx 组件主要用于页面导航时的 Loading UI。对于页面首次加载或刷新,需要通过状态管理和条件渲染来模拟 Loading 效果。通过合理使用 Loading UI,可以显著提升用户体验,让用户知道应用正在响应,并减少等待的焦虑感。










