We all know when to use "use client" and "use server" in Next.js or we can learn and go through in short here. But how to integrate "use client" and "use server" components in each other. If you have an idea about basic "use client" and "use server" you can jump on chapter 3 below.
Next.js is built on top of React.js, which is primarily a client-side library
Chapter 1: "use client"
What is "use client"?
The "use client" directive in Next.js is used to indicate that a specific component should be rendered on the client side.
When to use "use client"?
- Client-Side Interactivity: Like buttons.
- State Management: Like useState.
- Dynamic Data Fetch :data fetching based on user interaction.
- Third-Party Libraries: Like gsap;
"use client";
import { useState } from 'react';
function ClientCounter() {
const [count, setCount] = useState(0);
const increment = () => setCount(count + 1);
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>Increment</button>
</div>
);
}
export default ClientCounter;
Chapter 2: "use server"
What is "use server"?
The "use server" directive in Next.js is used to indicate that a specific component should be rendered on the server side.
When to use "use server"?
- Data Fetching on the Server: fetch data before rendering the component.
- Static Content: displaying static content.
- Server-Side Logic: execute logic that must happen before rendering.
"use server";
import React from 'react';
async function fetchData() {
return new Promise((resolve) => {
setTimeout(() => {
resolve("Hello from the server!");
}, 1000);
});
}
async function ServerGreeting() {
const data = await fetchData();
return <div>{data}</div>;
}
export default ServerGreeting;
Chapter 3: Integration
Any other tutorial will teach that we can use "use client" component inside "use server" component. As "use client" deals with user interactions. We can use "use client" inside "use server" without rendering problems.
But how can we use "use server" component in "use client" component? is it good idea?
First we will see examples:
Server component.
// Here we created a simple server component
"use server";
async function fetchUsers() {
const response = await fetch('https://jsonplaceholder.typicode.com/users');
return await response.json();
}
export async function ServerUserList() {
const users = await fetchUsers();
return (
<ul>
{users.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
}
Client component where we imported server component.
"use client";
// Importing server component
import { ServerUserList } from './ServerUserList';
function UserList() {
return (
<div>
<h1>User List</h1>
<ServerUserList /> {/* Server component used here */}
<p>This is a client component that allows for additional interactivity!</p>
</div>
);
}
export default UserList;
App/page.tsx
// HomePage
// Here we are importing UserList which is cliet componet.
import UserList from './components/UserList';
export default function HomePage() {
return (
<main>
<UserList />
</main>
);
}
- Here we are using server component inside client component.
- Here server component became client component ? No.
What happend here (ServerUserList) is the server component uses the "use server" directive, fetches user data from the API, and renders it as an unordered list. This data fetching happens on the server side.
The client component (UserList) uses the "use client" directive and imports ServerUserList. This means that ServerUserList is executed on the server, and its rendered output is sent to the client.
The HomePage component uses the UserList component, integrating both server and client components.
This code structure shows how to effectively use server components within client components in Next.js. The server component handles data fetching, while the client component can manage user interactions and additional logic.
Top comments (0)