我正在从返回随机笑话的api中抓取(使用Nextjs 13的fetch
与{cache:'force-cache'}
)。我注意到fetch
在构建过程中被调用了两次。
下面是我的代码:
// page.js
import {RefreshButton} from './RefreshButton'
async function getRandomJoke(){
const res = await fetch("https://v2.jokeapi.dev/joke/Programming?type=single", {cache:'force-cache'})
const data = await res.json()
console.log("fetch called. Joke is: ", data['joke'])
return data['joke']
}
export default async function Home() {
const joke = await getRandomJoke()
return (
<div>
{joke}
<RefreshButton/>
</div>
)
}
,下面是构建日志:
[= ] info - Generating static pages (2/3)fetch called. Joke is: A programmer puts two glasses on his bedside table before going to sleep. A full one, in case he gets thirsty, and an empty one, in case he doesn't.
[== ] info - Generating static pages (2/3)fetch called. Joke is: The generation of random numbers is too important to be left to chance.
当页面第一次呈现时,它显示第一个笑话。单击<RefreshButton />
(这是单击时调用router.refresh()
的客户端组件)后,将显示第二个笑话。
我的问题是:
- 为什么
fetch
在构建期间被调用两次? - 为什么它的数据在刷新时改变,如果它是静态生成的?
尝试在读取调用中使用revalidate,复制在此实现后停止
https://beta.nextjs.org/docs/data-fetching/revalidating
"next":"13.0.7"react"18.2.0">
我搜索了很多,最后我找到了这种方式,它对我很有效。我从react.dev找到了这个想法。
发生这种情况是因为服务器呈现带有一些初始状态的HTML,然后客户端JavaScript接管并初始化Zustand存储。如果初始状态与客户端JavaScript初始化的状态不同,可能会导致应用程序不一致。import { useEffect, useState } from "react"
const HydrationZustand = ({ children }) => {
const [isHydrated, setIsHydrated] = useState(false)
// Wait till Next.js rehydration completes
useEffect(() => {
setIsHydrated(true)
if(isHydrated)
//fetch you apis
}, [isHydrated])
return <>{isHydrated ? <div>{children}</div> : null}</>
}
export default HydrationZustand
更多信息请参见medium
使用下面的代码包装我们的应用程序:
import "../scss/style.default.scss
import Layout from "../components/Layout"
import HydrationZustand from "./hydrationZustand"
function App({ Component, pageProps }) {
return (
<HydrationZustand>
<Layout {...pageProps}>
<Component {...pageProps} />
</Layout>
</HydrationZustand>
)
}
export default App