如何让Next.js 13服务器组件每60秒重新渲染?
在Next.js 13服务器组件中实现每60秒重新渲染的方案
由于服务器组件无法直接使用客户端的useEffect和setTimeout,可以通过以下两种方案实现定时刷新:
方法一:客户端组件触发服务器组件重新挂载
通过客户端组件作为容器,定时更新key值触发服务器组件重新挂载,从而重新从数据库拉取数据:
- 保留原服务器组件
UsersLayout不变:
import { db } from "@utils/database"; export async function UsersLayout() { let users = await db.query(...); return ( <ul> {users.map(user => <li key={user.id}>{user.name}</li> )} </ul> ) }
- 创建客户端组件
UsersWrapper,添加定时逻辑:
'use client'; import { useState, useEffect } from 'react'; import { UsersLayout } from './UsersLayout'; export default function UsersWrapper() { const [refreshKey, setRefreshKey] = useState(0); useEffect(() => { const interval = setInterval(() => { setRefreshKey(prev => prev + 1); }, 60000); return () => clearInterval(interval); }, []); return <UsersLayout key={refreshKey} />; }
- 在页面或父组件中使用
UsersWrapper替代UsersLayout即可。
方法二:利用缓存标签触发数据刷新
通过unstable_cache为数据库查询添加缓存标签,再在客户端定时调用revalidateTag刷新缓存,让服务器组件获取最新数据:
- 改造服务器组件,包装查询并添加缓存标签:
import { db } from "@utils/database"; import { unstable_cache } from 'next/cache'; export async function UsersLayout() { const getUsers = unstable_cache( async () => db.query(...), ['users-data'], { tags: ['users'] } ); const users = await getUsers(); return ( <ul> {users.map(user => <li key={user.id}>{user.name}</li> )} </ul> ) }
- 创建客户端组件触发缓存刷新:
'use client'; import { useEffect } from 'react'; import { revalidateTag } from 'next/cache'; export default function UsersWrapper() { useEffect(() => { const interval = setInterval(() => { revalidateTag('users'); }, 60000); return () => clearInterval(interval); }, []); return <UsersLayout />; }
注意:unstable_cache属于Next.js不稳定API,后续版本可能会有调整,请留意官方更新。
内容的提问来源于stack exchange,提问作者Tomasz Mularczyk
相关产品推荐
相关产品推荐

