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

背景

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

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

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

3.客户端本地存储 (LocalStorage / SessionStorage)

LocalStorage 和 SessionStorage 是浏览器提供的 Web Storage API,允许你在用户的浏览器中存储键值对数据。LocalStorage 会一直保留数据直到被清除,而 SessionStorage 只在当前会话期间有效(浏览器关闭即丢失)。这种方法适用于需要在页面刷新或导航后仍然保留的数据,但仅限于客户端。

优点:

  • 可以存储更多数据,不像 URL 参数有长度限制。
  • 数据不会暴露在 URL 中。
  • 数据在页面刷新后仍然存在 (LocalStorage)。

缺点:

  • 只能在客户端使用,无法在 Server Component 中直接访问存储的数据来渲染初始页面。
  • 不适合存储敏感信息。
  • 用户可以清空存储。
  • 存储容量有限制(通常 5-10MB)。

适用场景:

  • 记住用户在上次访问时的选择或状态 (例如,购物车内容 - 更复杂的应用通常用后端或更高级的状态管理)。
  • 在多个步骤的表单中暂存数据。
  • 存储用户的 UI 偏好设置。

如何实现

发送数据 (存储):
在源页面或触发导航前的客户端代码中,将数据存入 LocalStorage 或 SessionStorage。

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
// 在源页面 (Client Component)

'use client';

import { useRouter } from 'next/navigation';
import { useState } from 'react';

function DataSender() {
const router = useRouter();
const [inputData, setInputData] = useState('');

const dataToStore = {
message: 'Hello from previous page!',
timestamp: new Date().toISOString(),
};

const handleSaveAndNavigate = () => {
// 将数据转换为 JSON 字符串存储
localStorage.setItem('myAppData', JSON.stringify(dataToStore));
sessionStorage.setItem('currentSessionData', JSON.stringify({ input: inputData }));

// 导航到目标页面
router.push('/destination');
};

return (
<div>
<h1>Source Page</h1>
<input
type="text"
value={inputData}
onChange={(e) => setInputData(e.target.value)}
placeholder="Enter some data"
/>
<button onClick={handleSaveAndNavigate}>
Save Data & Go to Destination
</button>
</div>
);
}

export default DataSender;

接收数据 (读取):
在目标页面(必须是 Client Component,因为 Web Storage API 是浏览器 API)中,从 LocalStorage 或 SessionStorage 中读取数据。通常在组件挂载后进行读取,以确保浏览器环境可用。

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
50
51
52
// app/destination/page.js (Client Component)

'use client';

import { useEffect, useState } from 'react';

function DestinationPage() {
const [localStorageData, setLocalStorageData] = useState(null);
const [sessionStorageData, setSessionStorageData] = useState(null);

useEffect(() => {
// 在组件挂载后读取数据
const storedData = localStorage.getItem('myAppData');
if (storedData) {
setLocalStorageData(JSON.parse(storedData)); // 将 JSON 字符串解析回对象
}

const sessionData = sessionStorage.getItem('currentSessionData');
if (sessionData) {
setSessionStorageData(JSON.parse(sessionData));
}

// (可选) 读取后可以清除存储的数据,如果它只用于单次页面传输
// localStorage.removeItem('myAppData');
// sessionStorage.removeItem('currentSessionData');

}, []); // 空依赖数组表示只在组件挂载时执行一次

return (
<div>
<h1>Destination Page</h1>
{localStorageData && (
<div>
<h2>Data from LocalStorage:</h2>
<p>Message: {localStorageData.message}</p>
<p>Timestamp: {localStorageData.timestamp}</p>
</div>
)}

{sessionStorageData && (
<div>
<h2>Data from SessionStorage:</h2>
<p>Input: {sessionStorageData.input}</p>
</div>
)}

{!localStorageData && !sessionStorageData && <p>No data found in storage.</p>}
</div>
);
}

export default DestinationPage;

总结和选择建议:

  • 对于需要在 URL 中可见、便于分享或作为资源标识符的数据,URL 查询参数 或 动态路由参数 是首选。
  • 如果数据与资源的身份紧密相关(例如,用户 ID, 产品 Slug),使用动态路由参数可以使 URL 更清晰。
  • 如果要传递多个可选的、不固定数量的数据,并且数据量不大,URL 查询参数通常更灵活。
  • 对于需要在页面刷新或跨标签页(LocalStorage)/ 同一个会话(SessionStorage)中保留的客户端状态数据,- 可以使用客户端本地存储,但要注意其局限性。

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

请我喝杯咖啡吧~

支付宝
微信