Next.js动态路由数据获取:页面刷新后产品信息丢失的解决方法
解决Next.js刷新产品详情页数据消失的问题
你的问题核心是:页面刷新时Redux Store会被重置,而产品详情页没有独立获取数据的逻辑,完全依赖之前目录页存在Redux里的数据。下面给你几个可行的解决办法:
方案1:详情页独立服务器端获取单产品数据(最推荐)
利用Next.js App Router的服务器组件特性,直接在产品详情页的page.tsx里单独请求当前产品的数据,不依赖Redux。这样不管是跳转还是刷新,页面都会自己获取数据。
示例代码(src/app/products/[id]/page.tsx):
import React from "react"; // 获取单个产品数据的异步函数 const getSingleProduct = async (id: string) => { try { const res = await fetch( `https://impilomedicalsystems.co.za/wp-json/wp/v2/product/${id}` ); if (!res.ok) throw new Error("Failed to fetch product"); return res.json(); } catch (error: any) { throw new Error(error.message); } }; // 服务器组件,接收路由参数 const ProductDetailPage = async ({ params }: { params: { id: string } }) => { const product = await getSingleProduct(params.id); // 渲染产品详情 return ( <div className="product-detail"> <h1>{product.title.rendered}</h1> {/* 其他产品信息 */} </div> ); }; export default ProductDetailPage;
方案2:Redux数据持久化到LocalStorage
如果一定要保留Redux存储数据的方式,可以用redux-persist把Store里的产品数据存在本地存储,刷新页面时自动从LocalStorage恢复数据。
步骤:
- 安装依赖:
npm install redux-persist
- 修改Redux Store配置(比如
@/app/store/store.ts):
import { configureStore } from "@reduxjs/toolkit"; import { persistStore, persistReducer } from "redux-persist"; import storage from "redux-persist/lib/storage"; // 默认用localStorage import productsReducer from "./slices/productsSlice"; import filterReducer from "./slices/filterSlice"; // 配置persist const persistConfig = { key: "root", storage, whitelist: ["products"], // 只持久化products切片 }; // 包装productsReducer const persistedProductsReducer = persistReducer(persistConfig, productsReducer); export const store = configureStore({ reducer: { products: persistedProductsReducer, filter: filterReducer, // 不需要持久化的保持原样 }, // 禁用序列化检查,避免persist相关的警告 middleware: (getDefaultMiddleware) => getDefaultMiddleware({ serializableCheck: false, }), }); export const persistor = persistStore(store);
- 在根组件(比如
src/app/layout.tsx)里用PersistGate包裹应用:
import { Provider } from "react-redux"; import { store, persistor } from "./store/store"; import { PersistGate } from "redux-persist/integration/react"; export default function RootLayout({ children, }: { children: React.ReactNode; }) { return ( <html lang="en"> <body> <Provider store={store}> <PersistGate loading={null} persistor={persistor}> {children} </PersistGate> </Provider> </body> </html> ); }
方案3:详情页客户端主动请求数据
如果不想改服务器组件,也不想用持久化,可以在产品详情页的客户端组件里,检查Redux是否有当前产品数据,没有就主动请求并更新Store。
示例代码(产品详情页组件):
"use client"; // 标记为客户端组件 import React, { useEffect } from "react"; import { useAppSelector, useAppDispatch } from "@/app/store/store"; import { fetchProduct } from "@/app/store/slices/productsSlice"; // 假设你有这个action const ProductDetail = ({ id }: { id: number }) => { const dispatch = useAppDispatch(); const product = useAppSelector(state => state.products.products.find(p => Number(p.id) === id) ); useEffect(() => { // 如果Redux里没有当前产品数据,就请求 if (!product) { dispatch(fetchProduct(id)); // 需要你在productsSlice里定义这个异步action } }, [id, product, dispatch]); if (!product) return <div>Loading...</div>; return ( <div> <h1>{product.title.rendered}</h1> {/* 渲染详情 */} </div> ); }; export default ProductDetail;
推荐优先用方案1,因为它符合Next.js App Router的设计理念,服务器端获取数据既快又能避免客户端状态依赖的问题。
内容的提问来源于stack exchange,提问作者Soret
相关产品推荐
相关产品推荐

