预请求数据
¥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
接受 key
和 fetcher
作为参数。
¥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.