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.
Top comments (0)