自2016年成立以来,Next.js一直对其路由有意见。它基于页面的方法允许开发人员指定他们希望这些页面何时被渲染(服务器、客户端,或为静态页面预渲染)。
然而,这种方法并不是没有一些不便之处。值得庆幸的是,托管平台背后的公司和Next.js的创建者Vercel已经听到了这些担忧。在5月4日发出重大升级的预告后,两周后发表了一篇博文,解释了Next.js路由器的一些重大变化。
Lee Robinson在Twitter上说:"
Next.js路由器正在进行重大升级!◆ 嵌套路由/布局◆ 客户端和服务器路由◆ React 18功能--startTransition、Suspense◆ 为服务器组件设计◆ 100%可增量采用
,预计很快会有RFC
/ Twitter"
Next.js 路由器获得重大升级!◆ 嵌套路由/布局◆ 客户端和服务器路由◆ React 18 功能 - startTransition, Suspense◆ 专为服务器组件设计◆ 100%可递增采用 预计很快会有 RFC。
![]()
在这篇文章中,如果你还不熟悉Next.js的路由器,你将了解它目前是如何工作的。然后,你会发现有哪些问题因此而发生,以及本次更新计划如何解决这些问题。
Next.js 路由目前是如何工作的
如上所述,Next.js使用基于页面的方法来创建路由。具体来说,这意味着在每个Next.js项目中,都存在一个pages 文件夹。在这个特殊的文件夹中,每个文件和文件夹都构成一个新的路由。
在pages 文件夹中,第一个根路由是index.js ,它在/ URL上渲染主页。你也可以为你的文件命名,并创建一个静态路由(例如,about.js 为/about 路由)。
同样地,文件夹也可以用来创建嵌套路由。例如,创建一个名为support 的文件夹,并在faq.js 内创建一个文件,将创建路由/support/faq 。
这里有一张图可以更好地说明这一点。

动态路由也被支持。通过在你的文件或文件夹名称中加入方括号,你可以创建一个动态路由。例如,/blog/[article-id].js 将支持多个路由,如/blog/1,/blog/nextjs-dynamic-routing, 等等。
Next.js 路由器的限制
不幸的是,这种方法有一个主要的限制。也就是说,尽管嵌套路由共享一个父路由,但你不能在它们之间共享状态或布局。
例如,以认证为例。在React中,使用react-router库,你可以创建自定义路由。例如,你可以创建一个受保护的路由来验证用户是否已登录。如果用户没有登录,该路由就会重定向他们,比如说到登录或注册页面。然后,你可以把这个受保护的路由分配给你的路由器中/authentication 下的任何路径。通过这样做,嵌套路由不必担心认证问题,因为父路由将为他们处理。
不幸的是,这种情况在Next.js中是不可能的。你可以创建一个自定义路由组件,但你必须把它单独包在每个受保护的页面上。
同样的问题也适用于布局。如果你的应用程序有一个仪表板,那么多个页面将共享一个类似的布局(导航、页脚等)。目前,将一个布局同时应用于多个页面的唯一方法是在应用程序层面上这样做。然后,这个布局将被应用于你的整个应用程序。不幸的是,如果你有多个布局,你必须在每个页面的基础上定义它们。
Next.js 路由器的变化
了解到这一切后,Vercel的团队决定修复这些限制。
路由创建的变化
首先,与pages 文件夹类似,将有一个新的文件夹称为app 。这是为了提供向后兼容性,并允许开发人员慢慢迁移到新的路由器。
然后,文件夹结构仍将决定新的路由。这意味着,dashboard 文件夹内的app 将被链接到/dashboard 路线。然而,有趣的地方在于这些路由里面的文件。
以前的路由器假定/pages 里面的每个文件都是一个新的路由。顺便说一下,这导致开发人员将他们的页面和非页面的React组件分开(即:Navbar,Header,Footer )。把像Navbar.js 这样的文件和主页(又名/pages/index.js )放在一起,会使路由器认为Navbar 是一个新的路由,而不是一个简单的子组件。因此,许多开发者不得不创建一个components 文件夹,将他们的不同组件分开。
然而,新的路由器假定每个文件都不是路由,除非明确说明。因此,要创建一个新的路由,你必须在文件夹内创建一个page.js 。
因此,我们以前的项目例子在新的路由器下会是这样的。

动态路由也被支持。有了这种新的格式,例如要有一个/blog/[article-id] 的URL,你就需要一个/app/blog/[article-id]/page.js 的文件夹结构。
简而言之,这里有一些文件夹结构和它们相应的路由。
/app/blog/[article-id]/page.js→/blog/[article-id]/app/blog/[category-id]/page.js→/blog/[category-id]/app/blog/[category-id]/[article-id]/page.js→/blog/[category-id]/[article-id]
嵌套式布局
布局也得到了更新。
以前,你可以在一个单独的文件中创建布局,然后将布局导入到你的页面。例如,这里是一个仪表板页面。
import DashboardLayout from '../components/DashboardLayout'
export default function DashboardPage() {
/* The content for your dashboard page */
}
DashboardPage.getLayout = function getLayout(page) {
return (
<DashboardLayout>
{page}
</DashboardLayout>
)
}
如果你需要嵌套它们,你可以导入多个布局到你的页面。然而,由于这是在每个页面的基础上进行的,所以嵌套在你的仪表板中的每个页面都必须导入布局并嵌套它们。
值得庆幸的是,这一点正在发生变化!有了新的路由器,你将能够为你的仪表盘页面指定一个布局,任何嵌套的页面将自动收到这个布局。你所要做的就是在文件夹中创建一个layout.js 文件,以便将这个布局应用到这个文件夹中的所有路由。
更具体地说,这里有一个例子。

在这个例子中,在根层创建了一个layout.js 文件,也就是在app 文件夹中。这个布局会自动应用于应用程序中的任何路线。
这个应用程序也有两个部分:仪表盘和支持。由于每个部分都拥有自己的风格,所以创建了一个layout.js 文件来为它们的路由应用特定的风格。在根布局的基础上,这意味着/dashboard 下的任何路由将收到应用程序的布局和仪表板的布局。
因此,pages.js 不再需要指定使用哪种布局,因为它是由layout.js 文件自动完成的。
与Next.js当前的路由器相反,它只允许你在页面层面上获取数据,你也将能够从布局中获取数据。你将能够使用getStaticProps 和getServerProps 来获取数据并建立你的布局。
因此,你的/dashboard 页面将能够从多个组件(应用程序的布局、仪表板的布局和页面本身)获取数据。
总结
我们已经快速浏览了Next.js当前的路由器是如何工作的以及它的局限性。然后,我们发现了Next.js的新路由器所带来的一些最大的变化,包括嵌套布局和新的子树导航。
Next.js路由器正在进行重大升级!◆ 嵌套路由/布局◆ 客户端和服务器路由◆ React 18功能--startTransition、Suspense◆ 为服务器组件设计◆ 100%可增量采用
,预计很快会有RFC
/ Twitter"