为什么Next.js的getServerSideProps中memoize不生效,如何缓存接口数据?
问题根因
你当前的memoize缓存不生效,核心原因是getCategory被定义在getServerSideProps函数内部:每次请求访问页面触发getServerSideProps执行时,都会重新创建一个全新的memoize函数实例,之前请求生成的缓存完全不会被复用,所以每次都会重新发起请求。
解决方案1:将memoize函数移到全局作用域
把getCategory的定义放到getServerSideProps外部,整个服务运行期间只会初始化一次memoize实例,缓存就可以正常生效:
import memoize from 'lodash.memoize' // 替换为你实际使用的memoize库 import axios from 'axios' // 移到全局作用域,仅初始化一次 const getCategory = memoize(async (url) => { console.log("getting category"); let response = await axios.get(url); return response.status ? response.data : false; }); export async function getServerSideProps(context) { let config = await import("../../config/config"); const requestUrl = `${config.default.apiEndpoint}&cAction=getCTGY&ctgyCode=${context.params.code}` const response = await getCategory(requestUrl); return { props: { category: response || null } }; }
注意:如果需要设置缓存过期时间、缓存上限,可以替换普通memoize为lru-cache这类支持过期淘汰的缓存库。另外这种内存缓存仅在单实例部署时生效,多实例部署可以考虑接入Redis这类公共缓存服务。
解决方案2:改用ISR静态增量渲染(更推荐)
如果分类数据的实时性要求不高,完全可以不用getServerSideProps,改用Next.js的getStaticProps搭配revalidate配置实现自动缓存更新,由Next.js框架层面帮你处理缓存逻辑,性能更高:
import axios from 'axios' export async function getStaticProps(context) { let config = await import("../../config/config"); const requestUrl = `${config.default.apiEndpoint}&cAction=getCTGY&ctgyCode=${context.params.code}` const response = await axios.get(requestUrl); return { props: { category: response.status ? response.data : null }, // 10秒后重新生成页面缓存,可根据业务需求调整时长 revalidate: 10 }; } // 配合getStaticPaths生成动态路由 export async function getStaticPaths() { // 可以先预生成热门分类的页面,剩下的访问时再生成 return { paths: [], fallback: 'blocking' }; }
这种方式下,同一个分类页面在缓存有效期内访问不会重复执行接口请求,还能在后台自动更新缓存内容。
内容的提问来源于stack exchange,提问作者Mike Willis
相关产品推荐
相关产品推荐

