首页
/ Next.js 应用路由中的页面组件(page.js)详解

Next.js 应用路由中的页面组件(page.js)详解

2025-07-05 01:22:25作者:郜逊炳

什么是页面组件

在 Next.js 的应用路由(App Router)架构中,page.js(或page.tsx)是一个核心概念文件,它定义了路由对应的用户界面。这个文件必须默认导出一个 React 组件,Next.js 会将其渲染为对应路由的页面内容。

基本用法

创建一个页面组件非常简单,只需在路由目录下创建一个page.js文件并导出组件:

// app/about/page.js
export default function AboutPage() {
  return <h1>关于我们</h1>
}

这样,访问/about路径时就会显示这个组件。

关键特性

  1. 文件扩展名支持:可以使用.js.jsx.tsx扩展名
  2. 路由结构:页面组件总是路由树的叶子节点
  3. 公开访问:必须有page.js文件才能使路由段可公开访问
  4. 默认服务端组件:页面默认是服务端组件,但可通过指令转为客户端组件

核心属性解析

params 属性

params是一个 Promise,解析后包含从根段到当前页面的动态路由参数对象。

// app/blog/[slug]/page.js
export default async function BlogPost({ params }) {
  const { slug } = await params
  return <h1>{slug}文章内容</h1>
}

参数示例

路由结构 访问URL params解析结果
app/shop/[id]/page.js /shop/123 { id: '123' }
app/cat/[sub]/page.js /cat/books { sub: 'books' }
app/[...slug]/page.js /a/b/c { slug: ['a', 'b', 'c'] }

searchParams 属性

searchParams也是一个 Promise,解析后包含当前URL的查询参数。

// app/search/page.js
export default async function SearchPage({ searchParams }) {
  const { q, page = '1' } = await searchParams
  return (
    <div>
      <h1>搜索: {q}</h1>
      <p>当前页码: {page}</p>
    </div>
  )
}

查询参数示例

访问URL searchParams解析结果
/search?q=next { q: 'next' }
/shop?sort=asc { sort: 'asc' }
/list?a=1&a=2 { a: ['1', '2'] }

进阶用法

在客户端组件中使用

虽然页面默认是服务端组件,但我们可以将其转为客户端组件并使用React的use钩子访问参数:

'use client'

import { use } from 'react'

export default function ClientPage({ params, searchParams }) {
  const { id } = use(params)
  const { filter } = use(searchParams)
  
  return <div>产品ID: {id}, 筛选条件: {filter}</div>
}

动态内容渲染

结合paramssearchParams可以实现丰富的动态内容:

// app/products/[category]/page.js
export default async function CategoryPage({ params, searchParams }) {
  const { category } = await params
  const { sort = 'popular', page = '1' } = await searchParams
  
  // 这里可以获取数据
  const products = await getProductsByCategory(category, { sort, page })
  
  return (
    <div>
      <h1>{category}分类</h1>
      <ProductList products={products} />
      <Pagination currentPage={parseInt(page)} />
    </div>
  )
}

版本演进

从Next.js 15开始,paramssearchParams变为Promise对象,这是为了更好的支持异步数据获取。在之前的版本中它们是同步属性,但这一行为将在未来被弃用。

最佳实践

  1. 参数验证:始终验证从URL获取的参数
  2. 默认值处理:为查询参数提供合理的默认值
  3. 错误处理:考虑参数缺失或无效的情况
  4. 性能优化:对于频繁变化的查询参数,考虑使用客户端状态管理

通过合理使用page.js组件及其参数,开发者可以构建出既灵活又高性能的Next.js应用页面。