NextJS三种页面数据传输方式 - 2

背景

在编写 NextJS 应用时,经常会出现需要在不同页面跳转,但希望能传输一定的数据,保持页面连续。在 Next.js App Router 中,有几种主要的方式可以在网页之间传输多个数据。选择哪种方式取决于你要传输的数据类型、大小以及是否需要在服务器端或客户端获取数据。

以下是几种常用的方法,我会详细解释并提供代码示例:

  1. URL 查询参数 (URL Query Parameters)
  2. 动态路由参数 (Dynamic Route Parameters)
  3. 客户端本地存储 (LocalStorage / SessionStorage)

2.动态路由参数 (Dynamic Route Parameters)

动态路由允许你在 URL 路径中嵌入可变的数据段,用于表示特定资源。例如,/users/[id] 路由可以捕获 /users/1 或 /users/abc 中的 id 部分作为参数。你可以创建多层级的动态路由来传递多个参数 (/products/[category]/[item])。

优点:

  • URL 结构更清晰,语义化更好,通常用于表示资源的层级关系。
  • 参数直接成为路由的一部分。
  • 可以在服务器端和客户端获取参数。

缺点:

  • 参数数量和结构需要在文件系统中预先定义好。
  • 不适合传递可选的、数量不固定的数据。

适用场景:

  • 显示特定用户信息 (/users/123)
  • 显示特定产品详情 (/products/electronics/iphone-13)
  • 博客文章详情 (/blog/my-first-post)

如何实现

定义动态路由:
在 app 目录下,创建带有方括号 [] 的文件夹或文件来定义动态路由。

发送数据 (通过链接或导航跳转):
构建符合动态路由结构的 URL。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// 在源页面

import Link from 'next/link';
import { useRouter } from 'next/navigation';

function ProductList() {
const router = useRouter();

const category = 'electronics';
const item = 'laptop-dell';

// 方法 1: 使用 next/link
const productUrl = `/products/${category}/${item}`;

const handleViewItem = (cat, itemName) => {
// 方法 2: 使用 router.push
router.push(`/products/${cat}/${itemName}`);
};

return (
<div>
<h1>Products</h1>
{/* 方法 1 示例 */}
<Link href={productUrl}>
View {item} in {category}
</Link>

<br />

{/* 方法 2 示例 */}
<button onClick={() => handleViewItem('books', 'the-hobbit')}>
View The Hobbit in Books
</button>
</div>
);
}

export default ProductList;

接收数据 (在目标页面):
在动态路由的 page.js 文件中,页面组件会接收一个 params prop,其中包含路由参数。

** Server Component: **

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// app/products/[category]/[item]/page.js (Server Component)

interface ProductPageProps {
params: Promise<{
category: string; // 对应 [category]
item: string; // 对应 [item]
}>
}

function async ProductPage({ params }: ProductPageProps) {
const { category, item } = await params; // 解构获取参数

console.log('Received params:', params);

return (
<div>
<h1>Category: {category}</h1>
<h2>Item: {item}</h2>
{/* 在 Server Component 中可以根据 category 和 item 获取产品详情 */}
</div>
);
}

export default ProductPage;

** Client Component: **

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// app/products/[category]/[item]/page.js (Client Component)
'use client'; // 标记为 Client Component

import React, { use } from "react";

interface ProductPageProps {
params: Promise<{
category: string; // 对应 [category]
item: string; // 对应 [item]
}>
}

function ProductPage({ params }: ProductPageProps) {
const parameters = use(params);
const { category, item } = parameters; // 解构获取参数

console.log('Received params:', parameters);

return (
<div>
<h1>Category: {category}</h1>
<h2>Item: {item}</h2>
</div>
);
}

export default ProductPage;

作者:Bearalise
出处:NextJS三种页面数据传输方式 - 2
版权:本文版权归作者所有
转载:欢迎转载,但未经作者同意,必须保留此段声明,必须在文章中给出原文链接。

请我喝杯咖啡吧~

支付宝
微信