Skip to content
开发文档
预请求

预请求数据

¥Prefetching Data

顶层页面数据

¥Top-Level Page Data

有很多方法可以预请求 SWR 数据。对于顶层请求,强烈建议使用 rel="preload" (opens in a new tab)

¥There’re many ways to prefetch the data for SWR. For top level requests, rel="preload" (opens in a new tab) is highly recommended:

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

只需将其放入 HTML <head> 中即可。它简单、快速且原生。

¥Just put it inside your HTML <head>. It’s easy, fast and native.

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

¥It will prefetch the data when the HTML loads, even before JavaScript starts to download. All your incoming fetch requests with the same URL will reuse the result (including SWR, of course).

以编程方式预请求

¥Programmatically Prefetch

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

¥SWR provides the preload API to prefetch the resources programmatically and store the results in the cache. preload accepts key and fetcher as the arguments.

即使在 React 之外,你也可以调用 preload

¥You can call preload even outside of React.

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 也可用于事件处理程序或效果。

¥Within React rendering tree, preload is also available to use in event handlers or effects.

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 中的 页面预请求 (opens in a new tab) 等技术,你将能够立即加载下一页和数据。

¥Together with techniques like page prefetching (opens in a new tab) in Next.js, you will be able to load both next page and data instantly.

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

¥In Suspense mode, you should utilize preload to avoid waterfall problems.

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>
  );
}

预填数据

¥Pre-fill Data

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

¥If you want to pre-fill existing data into the SWR cache, you can use the fallbackData option. For example:

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

如果 SWR 尚未获取数据,该钩子将返回 prefetchedData 作为后备。

¥If SWR hasn't fetched the data yet, this hook will return prefetchedData as a fallback.

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

¥You can also configure this for all SWR hooks and multiple keys with <SWRConfig> and the fallback option. Check Next.js SSG and SSR for more details.