Reputation: 43
I have a scenario that I must use the 'use client'
directive because my project uses Chakra UI and their components can't render in the server.
When I try running this sample code:
// 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 receive the expected output in my terminal running the next development server:
I am running server side!
But when I add the 'use client'
directive at the top of the file, I receive this duplicated message in my browser console:
I am running client side! (2)
I understand that the 'use client'
directive forces all the functions to be ran in the browser, but I can't understand why they run twice.
This is a problem because in my real project the line that awaits the Promise makes a request to a back end and Next.js can't cache these requests, resulting in duplicated requests hitting the API.
I tried to move the getData
function to another file and ran the project:
// 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>
)
}
And, for my surprise, I saw this in my next development server
I am running server side!
and this in my browser console
I am running client side! (2)
, making this hitting my API 3 times per page reload in my real application.
I also tried enabling 'Experimental Server Actions' in my next.config.js
and added the 'use server'
directive in app/otherFile.ts
. When I try to reload the page, it hangs indefinitely and doesn't show any output.
Why does this happen and how can I avoid this behaviour? Is this possible?
I'm using Next.js 13.4.4 and React 18.2.0.
Upvotes: 4
Views: 8057
Reputation: 79
You can test if it's React Strict mode causing the double render by disabling it in next.config.mjs
const nextConfig = {
compiler: {
styledComponents: {
// Enabled by default.
cssProp: true,
},
},
reactStrictMode: false
};
Upvotes: 4