将数据从 NextJS 中的上一页传递到 getServerSideProps

Gan*_*esh 11 server-side-rendering next.js

我正在使用 NextJS 开发一个类似电子商务的网站。

我将在页面中获取并显示产品列表/products。单击任何产品后,我将导航到/details/[productId],然后按如下方式获取这些产品详细信息。

// In /details/[productId].js file

export async function getServerSideProps({params}) {
    const res = await fetch(`https:my-api-url/api/products/${params.productId}`)
    const product = await res.json()
    return {
        props: {
            product
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

问题

直到这一步一切看起来都很好。但我想减少数据库读取次数,因此detail我计划使用在上一页 ( /products) 中获取的数据,其中包含有关产品的信息,而不是在页面中再次获取产品详细信息。因此,我需要一种方法将这些产品对象传递到下一个屏幕/details/[productId]的 getServerSideProps (以实现用于 SEO 目的的 SSR)。

解决方法

我目前拥有的一种解决方案是stringify产品 json 并通过查询参数传递它,然后将其返回到getServerSideProps({params, query}). 但它只是在浏览器中向我的网址发送垃圾邮件,这看起来一点也不好看。

期待

是否有其他方法将数据传递到getServerSideProps函数中,以便它将利用数据在服务器本身中生成整个页面。请指导我克服这个问题。任何帮助,将不胜感激。

提前致谢.. (:

Olu*_*ule 1

您可以快速引入自定义服务器,该服务器提供locals在应用程序或请求的整个生命周期内可用的属性。

const next = require('next');
const express = require('express');

const app = next({ dev: process.env.NODE_ENV !== 'production' });
const handle = routes.getRequestHandler(app);
const env = process.env.NODE_ENV || 'dev';


app.prepare().then(() => {
  const server = express();
   
  server.get('/products', async (req, reply) => {
    const products = await //... fetch product with details
    req.app.locals.products =  products;
    return app.render(req, reply, '/path/to/products/page', req.query);
  });
  
  server.get('/details/:productId', async (req, reply) => {
    const {productId} = req.params;
    const {products} = req.app.locals;
    // find product using productId and make available in req.locals
    req.locals.product = // product;
    return app.render(req, reply, '/path/to/product/detail/page', req.query)
  }); 
  
  server.get('*', (req, reply) => {
    return handle(req, reply)
  });

  server.listen(3000);
});

Run Code Online (Sandbox Code Playgroud)

请注意产品列表的增长量,以避免应用程序内存不足。

您还可以在产品请求中返回包含产品列表的 cookie(请参阅 HTTP cookie 的限制)。然后在产品详细信息页面上阅读该内容。