Next.js中如何在动态页面的getServerSideProps中获取_app的getInitialProps返回的全局数据
在Next.js的getServerSideProps中获取_app的getInitialProps返回的全局数据
这个问题其实是Next.js中服务端数据获取的常见场景——因为getInitialProps(在_app中)和页面的getServerSideProps是独立执行的,没办法直接共享数据,不过我们可以通过复用数据获取逻辑来解决,具体步骤如下:
1. 抽离全局数据的获取逻辑
首先把你在_app的getInitialProps中发送API请求的代码抽成一个独立的可复用函数,这样_app和动态页面的getServerSideProps都能调用它。
比如创建一个utils/globalData.js文件:
// 可选:添加内存缓存避免重复请求 let cachedGlobalData = null; export async function getGlobalData() { // 如果有缓存直接返回,避免重复API请求 if (cachedGlobalData) { return cachedGlobalData; } // 这里替换成你的实际API请求逻辑 const res = await fetch('https://your-api-domain/global-config'); const globalData = await res.json(); // 设置缓存过期时间(比如5分钟,根据你的业务需求调整) cachedGlobalData = globalData; setTimeout(() => { cachedGlobalData = null; }, 5 * 60 * 1000); return globalData; }
2. 在_app中使用这个共享函数
修改你的_app.js,调用抽离后的函数获取全局数据,并把它传递给所有页面:
import App from 'next/app'; import { getGlobalData } from '../utils/globalData'; function MyApp({ Component, pageProps, globalData }) { // 客户端可以通过props访问globalData,和你之前的逻辑一致 return <Component {...pageProps} globalData={globalData} />; } MyApp.getInitialProps = async (appContext) => { // 获取全局数据 const globalData = await getGlobalData(); // 获取页面的默认初始props const appProps = await App.getInitialProps(appContext); return { ...appProps, globalData }; }; export default MyApp;
3. 在动态页面的getServerSideProps中调用共享函数
现在你可以在pages/[dynamic].js的getServerSideProps里直接调用getGlobalData,拿到需要的全局数据来做重定向判断:
import { getGlobalData } from '../utils/globalData'; export async function getServerSideProps(context) { // 获取全局数据 const globalData = await getGlobalData(); // 提取当前动态路由的参数 const { dynamic } = context.params; // 假设你的全局数据里有一个allowedRoutes数组,存储允许访问的路由 const isRouteAllowed = globalData.allowedRoutes.includes(dynamic); // 如果路由不在允许列表中,执行重定向 if (!isRouteAllowed) { return { redirect: { destination: '/', // 替换成你要重定向的目标页面 permanent: false, // 临时重定向(302),如果是永久重定向可以设为true }, }; } // 如果路由合法,返回页面需要的props(可以把globalData也传下去给客户端用) return { props: { globalData, // 这里可以添加页面专属的其他props }, }; } export default function DynamicPage({ globalData }) { // 页面组件的渲染逻辑 return <div>欢迎访问合法的动态页面:{globalData.allowedRoutes.join(', ')}</div>; }
关键说明
- 为什么要抽离函数?因为
_app的getInitialProps和页面的getServerSideProps是在服务端(首次渲染时)独立运行的,它们没有共享的上下文,所以没办法直接传递数据。通过复用同一个数据获取函数,就能保证两边拿到的是相同的全局数据。 - 缓存的作用:添加内存缓存后,在同一个服务端请求周期内(比如首次渲染时,
_app和页面的getServerSideProps会先后执行),第二次调用getGlobalData会直接用缓存,避免重复发送API请求,提升性能。
内容的提问来源于stack exchange,提问作者Mooder
相关产品推荐
相关产品推荐

