kay-adamof
Posted on October 25, 2023
1 - How to use 'use client'
There are two ways to make a component client-side.
No.1: Add 'use client'
at the beginning of the file
By adding 'use client'
at the beginning of the file, it becomes a Client Component. I think this is the most basic configuration method.
// app/ClientComponent.tsx
'use client'
export default function ClientComponent(){
return (
<button onClick={()=>{
console.log('Hello, Client')
}}>BUTTON</button>
)
}
// app/page.tsx
import ClientComponent from './ClientComponent.tsx'
export default function Page(){
return(
<div>
<ClientComponent />
</div>
)
}
No.2: Pass through the file with 'use client'
Even if the component file itself does not have 'use client'
, you can make it a Client Component by importing it into another file with 'use client'
.
// app/ClientComponent.tsx
export default function ClientComponent(){
return (
<button onClick={()=>{
console.log('Hello, Client')
}}>BUTTON</button>
)
}
// app/client.ts
'use client'
export { default } from './ClientComponent.tsx'
// app/page.tsx
import ClientComponent from './client.ts'
export default function Page(){
return(
<div>
<ClientComponent />
</div>
)
}
Thanks to this specification, even if an external library component does not support Client Component, you can treat it as a Client Component by adding 'use client'
to an arbitrary file and importing/exporting it.
However, please note that I explain more in the following section.
2 - Do not directly nest Server Components
If you import Server Component directly into the file of a Client Component and nest it, the Server Component will be treated as a Client Component (due to the specification shown in No.2 earlier).
To prevent this, set {children} on the Client Component side and wrap it with the opening tag of the Client Component.
// ❌
// app/ServerComponent.tsx
export default function ServerComponent(){
return(
<div>Hello, Server</div>
)
}
// app/ClientComponent.tsx
'use client'
import ServerComponent from './ServerComponent.tsx'
export default function ClientComponent(){
return (
<button onClick={()=>{console.log("Hello, Client")}}>
<ServerComponent />
</button>
)
}
// app/page.tsx
import ClientComponent from './ClientComponent.tsx'
export default function Page(){
return(
<div>
<ClientComponent />
</div>
)
}
// ⭕️
// app/ServerComponent.tsx
export default function ServerComponent(){
return(
<div>Hello, Server</div>
)
}
// app/ClientComponent.tsx
'use client'
export default function ClientComponent(){
return (
<button onClick={()=>{console.log("Hello, Client")}}>
{ children }
</button>
)
}
// app/page.tsx
import ClientComponent from './ClientComponent.tsx'
import ServerComponent from './ServerComponent.tsx'
export default function Page(){
return(
<div>
<ClientComponent>
<ServerComponent />
</ClientComponent>
</div>
)
}
It is not necessary to always wrap it with the opening tag. However, you don't want to bring what can be generated on the server side to the client side, right?
3 - Do not import modules from index files (cannot)
CAUTION
This section was incorrect.
You cannot import from an index.ts/js
file into a Client Component.
// CAN NOT DO THIS
// lib/index.ts
export const sayHello = () => {console.log('Hello')
// app/ClientComponent.tsx
'use client'
import { sayHello } from '../lib'
export default function ClientComponent(){
return (
<button onClick={()=>{
sayHello()
}}>
You can't do this with ERROR
</button>
)
}
If you try to do this, you will get the following error.
4 - Pre-Rendering
Client components are first rendered on the server side.
The official documentation mentions the following.
For example, let's say you accidentally use a function inside the component that relies on the document
object.
// getDataTheme.ts
export const getDataTheme = () =>
document.documentElement.getAttribute('data-theme')
// Button.tsx
'use client'
import {getDataTheme} from './getDataTheme'
export default function Button(){
return (
<div>{getDataTheme()==='dark'?'Moon':'Sun'}</div>
)
}
In this case, you will likely see the following warning:
ReferenceError: document is not defined
This is likely caused by using a client-side API on the server side. Find a way to avoid this issue.
I have summarized the knowledge when creating Client Components. I hope it will be helpful to you.
That's all.
Posted on October 25, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 29, 2024
November 27, 2024