问题
我有一个场景,我必须使用'use client'
指令,因为我的项目使用Chakra UI,它们的组件无法在服务器中呈现。
当我尝试运行以下示例代码时:
// app/page.tsx
export async function getData() {
const side = typeof window === 'undefined' ? 'server' : 'client'
console.log(`I am running ${side} side!`)
const dados = await Promise.resolve([{ name: 'Hi' }, { name: 'Hello' }])
return dados
}
export default async function Home() {
const data = await getData()
return (
<ul>
{data.map(({ name }: any) =>
<li key={name}>{name}</li>
)}
</ul>
)
}
我在运行下一个开发服务器的终端中收到预期的输出:
I am running server side!
但是,当我在文件顶部添加'use client'
指令时,我在浏览器控制台中收到以下重复消息:
I am running client side! (2)
- 我知道
'use client'
指令强制所有函数在浏览器中运行 *,**但我不明白为什么它们会运行两次。**这是一个问题,因为在我的实际项目中,等待Promise的行向后端发出请求,而Next.js无法缓存这些请求,导致重复的请求击中API。
我所尝试的
多个文件
我尝试将getData
函数移动到另一个文件中,并运行该项目:
// app/otherFile.ts
export async function getData() {
const side = typeof window === 'undefined' ? 'server' : 'client'
console.log(`I am running ${side} side!`)
const dados = await Promise.resolve([{ name: 'Hi' }, { name: 'Hello' }])
return dados
}
// app/page.tsx
import { getData } from './otherFile'
export default async function Home() {
const data = await getData()
return (
<ul>
{data.map(({ name }: any) =>
<li key={name}>{name}</li>
)}
</ul>
)
}
而且,令我惊讶的是,我在我的下一个开发服务器中看到了这个
I am running server side!
- 和**这在我的浏览器控制台
I am running client side! (2)
,使得在我的实际应用程序中,每次页面重新加载都会命中我的API 3次。
实验服务器动作
我还尝试在我的next.config.js
中启用'Experimental Server Actions',并在app/otherFile.ts
中添加了'use server'
指令。当我尝试重新加载页面时,它会无限期挂起,并且不显示任何输出。
下一步?
为什么会发生这种情况,我如何避免这种行为?这可能吗?
我使用的是Next.js 13.4.4和React 18.2.0。
2条答案
按热度按时间xmq68pz91#
尽管双重呈现在开发过程中可能不方便,但在部署时它不应影响应用程序的功能或性能。
问题可能与React18有关。你可以在这里看到:https://github.com/vercel/next.js/issues/35822
您可以通过将reactStrictMode选项设置为true或false来尝试在next.config.js文件中启用或禁用严格模式。
我希望这些信息会有帮助。
56lgkhnf2#
这可能是因为Next.js会运行页面两次,一次在服务器上,一次在浏览器中。为了避免重复API调用,我们可以尝试使用React的
useEffect
钩子来确保getData
函数只被调用一次。下面是一个例子:希望这有帮助!如果您有更多问题,请随时联系!