SWR预取数据时如何避免重复请求?

Mr-振杰 阅读 49

在列表页预取详情数据时,发现每次滚动加载新条目都会触发重复的SWR请求。我尝试用useEffect结合swr/mutate缓存数据,但控制台还是显示重复的GET请求,该怎么优化?


import useSwr from 'swr'

function ListPage() {
  const { data: items } = useSwr('/api/items')
  const mutate = useSwrConfig().mutate

  useEffect(() => {
    items?.forEach(item => {
      mutate(/api/item/${item.id}, { data: item }, { revalidate: false })
    })
  }, [items, mutate])

  return items?.map(item => (
    <ItemPreview key={item.id} item={item} />
  ))
}

问题出现在点击预览项进入详情页时,明明缓存存在却依然发送了新请求,页面加载动画还会闪一下。这种预取场景应该怎么做才对?

我来解答 赞 10 收藏
二维码
手机扫码查看
2 条解答
设计师树遥
按照规范,SWR 的预取机制可以通过 preload 或者 mutate 来实现,但是从你的描述来看,主要问题是预取的数据没有被正确地缓存或者缓存没有被正确地利用。你提到在点击预览项进入详情页时,尽管缓存存在,仍然发送了新的请求,这可能是因为 SWR 在某些情况下不会自动使用缓存。

你可以尝试在预取时直接使用 mutate 的第三个参数 { populateCache: true, revalidate: false } 来确保数据被正确地填充到缓存中,而不会触发重新验证。同时,确保你在详情页使用 useSwr 获取数据时,SWR 能够识别并使用缓存。

以下是修改后的代码示例:

import useSwr from 'swr'
import { useSwrConfig } from 'swr'

function ListPage() {
const { data: items } = useSwr('/api/items')
const { mutate } = useSwrConfig()

useEffect(() => {
items?.forEach(item => {
// 使用 mutate 预先填充缓存
mutate(/api/item/${item.id}, item, { populateCache: true, revalidate: false })
})
}, [items, mutate])

return items?.map(item => (

))
}

function ItemDetail({ id }) {
// 在详情页使用 useSwr 获取数据
const { data: item } = useSwr(/api/item/${id})

if (!item) return
Loading...


return
{item.name}

}


在这个例子中,mutatepopulateCache: true 确保了数据被添加到缓存中,而 revalidate: false 则阻止了立即重新验证。这样可以避免不必要的网络请求。希望这能解决你的问题。
点赞
2026-03-23 19:03
百里素香
useSWRPreload 或者手动控制 revalidate 的时机,别让详情页的请求重复触发。把预取逻辑放到列表滚动加载的地方,确保只在必要时调用。

function ListPage() {
const { data: items } = useSwr('/api/items')
const { cache } = useSwrConfig()

useEffect(() => {
items?.forEach(item => {
if (!cache.has(/api/item/${item.id})) {
cache.set(/api/item/${item.id}, item)
}
})
}, [items, cache])

return items?.map(item => (

))
}


差不多这样就行,关键是提前把数据塞到缓存里,详情页直接读缓存,别再触发网络请求了。
点赞 8
2026-02-17 16:00