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

背景

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

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

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

1.URL 查询参数 (URL Query Parameters)

这是在页面之间传递少量、非敏感数据的最常见和灵活的方式。数据以键值对的形式附加在 URL 的问号后面 (?key1=value1&key2=value2)。

优点:

  • 实现简单,易于理解。
  • 可以在服务器端和客户端获取数据。
  • 用户可以直接修改 URL 参数,方便分享或书签。
  • 可以传递多个不同的数据字段。

缺点:

  • URL 长度有限制,不适合传递大量数据。
  • 数据暴露在 URL 中,不适合传递敏感信息。
  • 只能传递字符串类型的数据(数字、布尔值等需要转换)。

适用场景:

  • 搜索结果过滤 (/products?category=electronics&sort=price)
  • 分页 (/articles?page=2&limit=10)
  • 传递简单的用户偏好或状态 (/settings?theme=dark)
  • 在不同页面间传递 ID 或标识符

如何实现

发送数据 (通过链接或导航跳转):
你可以使用 next/link 组件或 next/navigation 中的 useRouter 来构建带有查询参数的 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
39
40
41
42
43
44
45
46
47
48
49
// 在源页面 (例如 pages/dashboard/page.js 或 components/SomeComponent.js)

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

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

const dataToPass = {
userId: 123,
status: 'active',
showDetails: true,
};

// 方法 1: 使用 next/link
// 注意:Link 组件会自动处理客户端路由跳转
const queryString = new URLSearchParams(dataToPass).toString(); // 构造查询字符串
const targetUrl = `/profile?${queryString}`; // 目标页面路径加上查询参数

const handleClick = () => {
// 方法 2: 使用 router.push 进行编程式导航
// 同样需要构造查询字符串
const dataForPush = {
productId: 'abc',
color: 'red',
size: 'M',
};
const queryParamsForPush = new URLSearchParams(dataForPush).toString();
router.push(`/product-detail?${queryParamsForPush}`);
};

return (
<div>
{/* 方法 1 示例 */}
<Link href={targetUrl}>
Go to Profile with Data
</Link>

<br />

{/* 方法 2 示例 */}
<button onClick={handleClick}>
Go to Product Detail with Data
</button>
</div>
);
}

export default MyComponent;

接收数据 (在目标页面):
在目标页面(例如 app/profile/page.js 或 app/product-detail/page.js),你可以使用 next/navigation 中的 useSearchParams Hook (在 Client Component 中) 或通过 searchParams 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
25
26
27
28
29
30
31
32
33
34
// app/profile/page.js (Client Component)

'use client'; // 标记为 Client Component

import { useSearchParams } from 'next/navigation';

function ProfilePage() {
const searchParams = useSearchParams();

// 获取单个参数
const userId = searchParams.get('userId');
const status = searchParams.get('status');
const showDetails = searchParams.get('showDetails') === 'true'; // 注意布尔值需要手动转换

// 或者遍历所有参数
const allParams = {};
for (const [key, value] of searchParams.entries()) {
allParams[key] = value;
}

console.log('All query params:', allParams);

return (
<div>
<h1>User Profile</h1>
<p>User ID: {userId}</p>
<p>Status: {status}</p>
<p>Show Details: {showDetails ? 'Yes' : 'No'}</p>
{/* ...其他页面内容 */}
</div>
);
}

export default ProfilePage;

在 Server Component 中获取:
Server Components 可以通过接收 searchParams prop 来获取查询参数。

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
// app/product-detail/page.js (Server Component)

// 这是一个 Server Component,不需要 'use client'

interface ProductDetailPageProps {
searchParams: { [key: string]: string | string[] | undefined };
}

function ProductDetailPage({ searchParams }: ProductDetailPageProps) {
// 直接从 searchParams 对象访问参数
const productId = searchParams.productId;
const color = searchParams.color;
const size = searchParams.size;

console.log('Received search params in Server Component:', searchParams);

return (
<div>
<h1>Product Detail</h1>
<p>Product ID: {productId}</p>
<p>Color: {color}</p>
<p>Size: {size}</p>
{/* 在 Server Component 中可以根据这些参数获取产品数据 */}
</div>
);
}

export default ProductDetailPage;

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

请我喝杯咖啡吧~

支付宝
微信