跳至内容
文档
预取

预取数据

顶级页面数据

有很多方法可以预取 SWR 的数据。对于顶级请求,rel="preload" (在新标签页中打开) 强烈推荐。

<link rel="preload" href="/api/data" as="fetch" crossorigin="anonymous">

只需将其放在你的 HTML <head> 中。它简单、快速且原生。

它将在 HTML 加载时预取数据,甚至在 JavaScript 开始下载之前。所有具有相同 URL 的传入获取请求将重用结果(当然包括 SWR)。

以编程方式预取

SWR 提供了 preload API 以编程方式预取资源并将结果存储在缓存中。 preload 接受 keyfetcher 作为参数。

你甚至可以在 React 以外调用 preload

import { useState } from 'react'
import useSWR, { preload } from 'swr'
 
const fetcher = (url) => fetch(url).then((res) => res.json())
 
// Preload the resource before rendering the User component below,
// this prevents potential waterfalls in your application.
// You can also start preloading when hovering the button or link, too.
preload('/api/user', fetcher)
 
function User() {
  const { data } = useSWR('/api/user', fetcher)
  ...
}
 
export default function App() {
  const [show, setShow] = useState(false)
  return (
    <div>
      <button onClick={() => setShow(true)}>Show User</button>
      {show ? <User /> : null}
    </div>
  )
}

在 React 渲染树中,preload 也可用于事件处理程序或效果。

function App({ userId }) {
  const [show, setShow] = useState(false)
 
  // preload in effects
  useEffect(() => {
    preload('/api/user?id=' + userId, fetcher)
  }, [userId])
 
  return (
    <div>
      <button
        onClick={() => setShow(true)}
        {/* preload in event callbacks */}
        onHover={() => preload('/api/user?id=' + userId, fetcher)}
      >
        Show User
      </button>
      {show ? <User /> : null}
    </div>
  )
}

结合 Next.js 中的 页面预取 (在新标签页中打开) 等技术,你将能够立即加载下一页和数据。

在 Suspense 模式下,你应该使用 preload 来避免瀑布问题。

import useSWR, { preload } from 'swr'
 
// should call before rendering
preload('/api/user', fetcher);
preload('/api/movies', fetcher);
 
const Page = () => {
  // The below useSWR hooks will suspend the rendering, but the requests to `/api/user` and `/api/movies` have started by `preload` already,
  // so the waterfall problem doesn't happen.
  const { data: user } = useSWR('/api/user', fetcher, { suspense: true });
  const { data: movies } = useSWR('/api/movies', fetcher, { suspense: true });
  return (
    <div>
      <User user={user} />
      <Movies movies={movies} />
    </div>
  );
}

预填充数据

如果要将现有数据预填充到 SWR 缓存中,可以使用 fallbackData 选项。例如

useSWR('/api/data', fetcher, { fallbackData: prefetchedData })

如果 SWR 尚未获取数据,则此钩子将返回 prefetchedData 作为回退。

你还可以使用 <SWRConfig>fallback 选项为所有 SWR 钩子以及多个键配置此选项。有关更多详细信息,请查看 Next.js SSG 和 SSR