NextJS中如何将Koa的server.js生成的数据传递给_app.js或页面?
解决方案
1. 将server.js数据传递到_app.js的实现方式
你可以直接将自定义数据挂载到Koa的请求对象req上,NextJS服务端渲染时getInitialProps拿到的ctx.req和Koa层的请求对象是同一个实例,直接读取即可:
修改server.js代码
router.get("(.*)", async (ctx) => { const name = ctx.query.name; if (verified_names[name] === undefined) { ctx.redirect(`/verify_name?name=${name}`); // 重定向后终止后续渲染逻辑 return } var custom_data = custom_logic(verified_names[name]); // 核心:将自定义数据挂载到请求对象上 ctx.req.custom_data = custom_data await handle(ctx.req, ctx.res); });
修改_app.js代码
import App from 'next/app' import { createContext, useContext } from 'react' // 全局上下文,所有页面都能通过这个上下文拿到数据 const CustomDataContext = createContext(null) class MyApp extends App { render() { const { Component, pageProps, customData } = this.props return ( <CustomDataContext.Provider value={customData}> <Component {...pageProps} /> {/* 可选:将数据挂载到window,供客户端导航时读取 */} <script dangerouslySetInnerHTML={{ __html: `window.__CUSTOM_DATA__ = ${JSON.stringify(customData)}` }} /> </CustomDataContext.Provider> ) } } MyApp.getInitialProps = async ({ ctx }) => { const appProps = await App.getInitialProps(ctx) // 服务端渲染时从req取数据,客户端导航时从window取数据 const customData = ctx.req ? ctx.req.custom_data : window.__CUSTOM_DATA__ return { ...appProps, customData } }; export default MyApp // 封装成hook,其他页面直接调用即可拿到全局数据 export const useCustomData = () => useContext(CustomDataContext)
2. 重定向逻辑是否可以迁移到_app.js
可以迁移,但要根据场景选择:
- 迁移后你可以在
_app.js的getInitialProps服务端阶段直接读取内存中的verified_names对象,重定向逻辑可以用ctx.res.writeHead(302, { Location:/verify_name?name=${ctx.query.name}}).end()实现 - 放在
server.js的性能更好,无需进入NextJS的渲染流程就可以直接完成重定向 - 如果后续你需要将项目部署到Serverless环境、或者做静态导出,内存中的
verified_names会失效,建议将验证数据迁移到Redis这类公共存储中,两种存放逻辑的方式都可以正常运行
内容的提问来源于stack exchange,提问作者avocado
相关产品推荐
相关产品推荐

