Next.js 13 App Router中如何以State跨页面传递previewData?
解决方案
一、最直接方案:利用Next.js导航的State参数(无需额外依赖)
完全符合你的需求——不用query或props,通过导航时的隐式state传递数据,仅存在客户端内存中,不会暴露在URL里。
1. 修改MainComponent.jsx(添加导航逻辑)
补充导航按钮,并在跳转时传入previewData作为state:
"use client"; import { useRouter } from "next/navigation"; // 示例数据源,根据实际情况替换 const images = [ { id: 1, title: "示例图片1", imageUrl: "/image1.jpg" }, { id: 2, title: "示例图片2", imageUrl: "/image2.jpg" } ]; const MainComponent = () => { const router = useRouter(); // App Router中客户端组件获取URL参数的方式 const searchParams = new URLSearchParams(window.location.search); const id = searchParams.get("id"); const imageData = images.find((image) => image.id === parseInt(id)); let previewData = null; if (imageData) { previewData = { id: imageData.id, title: imageData.title, imageUrl: imageData.imageUrl, }; } const navigateToResult = () => { if (previewData) { // 跳转时传入state数据 router.push("/result", { state: previewData }); } }; return ( <div> {previewData ? ( <div> <h1>{previewData.title}</h1> <button onClick={navigateToResult}>跳转到结果页</button> </div> ) : ( <div> <p>Loading...</p> </div> )} </div> ); }; export default MainComponent;
2. 修改Result.jsx(接收并展示state)
标记为客户端组件,通过useRouter()获取导航传入的state:
"use client"; import { useRouter } from "next/navigation"; import { useEffect, useState } from "react"; const Result = () => { const router = useRouter(); const [previewData, setPreviewData] = useState(null); useEffect(() => { // 获取导航时传递的state if (router.state) { setPreviewData(router.state); } }, [router.state]); if (!previewData) { return <div>Loading...</div>; } return ( <div> <h2>结果页展示数据</h2> <p>ID: {previewData.id}</p> <p>标题: {previewData.title}</p> <img src={previewData.imageUrl} alt={previewData.title} /> </div> ); }; export default Result;
二、进阶方案:全局状态管理(适合复杂场景)
如果你的应用需要在多个组件间共享状态,或需要持久化数据,可以用轻量状态库如Zustand:
1. 安装Zustand
npm install zustand
2. 创建全局状态store
在app目录下新建store.js:
import { create } from 'zustand'; export const usePreviewStore = create((set) => ({ previewData: null, setPreviewData: (data) => set({ previewData: data }), }));
3. 修改MainComponent.jsx(设置全局状态)
"use client"; import { useRouter } from "next/navigation"; import { usePreviewStore } from "@/app/store"; const images = [ { id: 1, title: "示例图片1", imageUrl: "/image1.jpg" }, { id: 2, title: "示例图片2", imageUrl: "/image2.jpg" } ]; const MainComponent = () => { const router = useRouter(); const setPreviewData = usePreviewStore((state) => state.setPreviewData); const searchParams = new URLSearchParams(window.location.search); const id = searchParams.get("id"); const imageData = images.find((image) => image.id === parseInt(id)); let previewData = null; if (imageData) { previewData = { id: imageData.id, title: imageData.title, imageUrl: imageData.imageUrl, }; } const navigateToResult = () => { if (previewData) { setPreviewData(previewData); router.push("/result"); } }; return ( <div> {previewData ? ( <div> <h1>{previewData.title}</h1> <button onClick={navigateToResult}>跳转到结果页</button> </div> ) : ( <div> <p>Loading...</p> </div> )} </div> ); }; export default MainComponent;
4. 修改Result.jsx(获取全局状态)
"use client"; import { usePreviewStore } from "@/app/store"; const Result = () => { const previewData = usePreviewStore((state) => state.previewData); if (!previewData) { return <div>Loading...</div>; } return ( <div> <h2>结果页展示数据</h2> <p>ID: {previewData.id}</p> <p>标题: {previewData.title}</p> <img src={previewData.imageUrl} alt={previewData.title} /> </div> ); }; export default Result;
方案对比
- 导航State方案:适合单次跨页面传值,无需额外依赖,实现简单,但刷新页面后状态会丢失。
- 全局状态管理方案:适合多组件共享状态,可结合localStorage实现持久化,但需要引入第三方库。
内容的提问来源于stack exchange,提问作者Auvee
相关产品推荐
相关产品推荐

