SWR Hook未同步数据库更新:AWS Lambda部署的Next.js访问量统计异常
根因说明
该问题是生产环境下SWR缓存策略和Next.js API路由缓存机制共同作用导致:本地开发环境SWR默认开启高频重校验,且API路由不会强制缓存,逻辑运行正常;部署到AWS Lambda后,API响应被缓存,且SWR未触发主动更新,因此一直展示首次拉取的数值。
解决思路
- 1. 访问量上报后主动触发SWR缓存更新
在ViewsCounter组件的POST请求完成后,调用SWR的mutate方法主动拉取最新数据,同个SWR key(/api/views/${slug})对应的所有组件(包括ViewsDisplay)都会同步更新数据。
修改后的ViewsCounter代码如下:
import useSWR, { useSWRConfig } from 'swr' function ViewsCounter({ slug }: { slug: string }) { const { data } = useSWR(`/api/views/${slug}`, fetcher); const { mutate } = useSWRConfig() const views = new Number(data?.total); useEffect(() => { const registerView = async () => { await fetch(`/api/views/${slug}`, { method: "POST" }) .catch(console.log); // 主动更新对应key的SWR缓存 mutate(`/api/views/${slug}`) }; registerView(); }, [slug, mutate]); return ( <> {views} </> ); }
- 2. 禁用访问量统计接口的缓存
在/api/views/[slug]的API路由处理函数中添加响应头,禁止CDN和浏览器缓存该接口的响应,避免SWR拉取到过期的缓存数据:
// API路由处理逻辑示例 export default function handler(req, res) { // 添加该行禁用缓存 res.setHeader('Cache-Control', 'no-store, max-age=0, must-revalidate') // 原有业务逻辑 if (req.method === 'POST') { // 更新数据库访问量逻辑 } else { // 查询访问量逻辑 } }
- 3. 调整SWR重校验配置(可选)
如果需要用户重新打开页面、切换回标签页时自动更新访问量,可以给useSWR添加重校验配置:
// 单个请求配置 const { data } = useSWR(`/api/views/${slug}`, fetcher, { revalidateOnFocus: true, // 页面聚焦时重校验 revalidateOnMount: true, // 组件挂载时重校验 dedupingInterval: 0 // 关闭请求去重,确保每次调用都发请求 })
如果需要全局生效,可以在SWR的全局配置Provider中添加上述参数。
内容的提问来源于stack exchange,提问作者Igniter
相关产品推荐
相关产品推荐

