NextJS中不使用Props向动态页面传递数据的方法求助
问题原因分析
React Context 仅在同一 React 组件树内生效,而 NextJS 中页面跳转后,原页面组件会被卸载,新页面是独立的根组件,因此无法跨页面读取之前的 Context 值。
以下是几种无需重复请求数据的解决方案:
方案1:URL传ID + NextJS 请求缓存
通过 URL 传递项目 ID,利用 NextJS 的缓存机制避免重复请求:
步骤1:在详情页传递ID
修改 projectInfo.jsx 的跳转链接:
<Link href={{ pathname: '/Report', query: { projectId: id } }} > <span className="mt-2 bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"> Create Report </span> </Link>
步骤2:报表页读取缓存数据
在 Report.jsx 中,通过带缓存的 fetch 复用之前的请求结果:
export default function ReportPage({ searchParams }) { const [project, setProject] = useState(null); useEffect(() => { if (!searchParams.projectId) return; // 开启强制缓存,复用之前的请求结果 fetch(`/projects/get/${searchParams.projectId}`, { cache: 'force-cache' }) .then(res => res.json()) .then(data => setProject(data)) .catch(err => console.error('获取数据失败:', err)); }, [searchParams.projectId]); return ( <div> {project && ( <div> <h2>报表:{project.title}</h2> {/* 渲染报表内容 */} </div> )} </div> ); }
如果使用 App Router 的 Server Components,可直接在组件内调用缓存的请求:
async function ReportPage({ searchParams }) { // NextJS 会自动缓存该请求,无需额外配置 const res = await fetch(`/projects/get/${searchParams.projectId}`); const project = await res.json(); return <div>{/* 报表内容 */}</div>; }
方案2:客户端本地存储(localStorage/sessionStorage)
将详情页请求到的数据存入本地存储,报表页直接读取:
步骤1:详情页存储数据
修改 projectInfo.jsx 的 fetch 回调:
.then((data) => { setProject(data); // 存入localStorage,用ID作为键名避免冲突 localStorage.setItem(`project_${id}`, JSON.stringify(data)); })
步骤2:报表页读取缓存
在 Report.jsx 中优先读取本地存储,可选静默刷新数据:
export default function ReportPage({ searchParams }) { const [project, setProject] = useState(null); useEffect(() => { if (!searchParams.projectId) return; const cacheKey = `project_${searchParams.projectId}`; const cachedData = localStorage.getItem(cacheKey); if (cachedData) { // 直接使用缓存数据 setProject(JSON.parse(cachedData)); // 可选:后台静默刷新数据,更新缓存 fetch(`/projects/get/${searchParams.projectId}`) .then(res => res.json()) .then(freshData => { setProject(freshData); localStorage.setItem(cacheKey, JSON.stringify(freshData)); }); } else { // 缓存不存在时发起请求 fetch(`/projects/get/${searchParams.projectId}`) .then(res => res.json()) .then(data => { setProject(data); localStorage.setItem(cacheKey, JSON.stringify(data)); }); } }, [searchParams.projectId]); return ( <div> {project && <div>报表内容:{/* ... */}</div>} </div> ); }
方案3:App Router 专属 React Cache
如果使用 NextJS 13+ 的 App Router,可通过 React 内置的 cache 函数实现跨组件请求复用:
步骤1:定义缓存请求函数
创建 lib/projects.js:
import { cache } from 'react'; export const getProject = cache(async (projectId) => { const res = await fetch(`/projects/get/${projectId}`); if (!res.ok) throw new Error('获取项目数据失败'); return res.json(); });
步骤2:详情页调用
async function ProjectInfoPage({ params }) { const project = await getProject(params.id); return ( <div> <h1>{project.title}</h1> <Link href={`/Report?projectId=${params.id}`}>Create Report</Link> </div> ); }
步骤3:报表页调用
async function ReportPage({ searchParams }) { // 复用之前的缓存结果,不会重复发起请求 const project = await getProject(searchParams.projectId); return <div>{/* 报表内容 */}</div>; }
内容的提问来源于stack exchange,提问作者Sid
相关产品推荐
相关产品推荐

