# Server vs Client Components & Router Hooks

## Server vs Client Components & Router Hooks

### 1. Understanding Server vs. Client Components

* **Server Components (Default in Next.js):**
  * **Purpose:** Render on the server side.
  * **Usage:** Ideal for data fetching, accessing backend resources (e.g., using an ORM), and rendering static content.
  * **Limitations:** Cannot use stateful or interactive hooks (like `useState`, `useEffect, useParams, useRouter,` useSearchParams.) or browser-only APIs (e.g., localStorage, geolocation).
* **Client Components:**

  * **Purpose:** Render on the client side.

  * **Usage:** Necessary when you need interactivity—such as event listeners, state management, or using browser APIs.

  * **Declaration:** Add `"`<mark style="color:red;">`use client`</mark>`"` at the top of your file to mark it as a client component.

  > **Tip:** Use server components when no interactivity is needed to reduce client-side JavaScript load, and switch to client components only when interactive behavior is required.

***

### 2. Converting a Component to a Client Component

#### a. Identify an Interactive Component

For example, imagine you have a page that needs to use <mark style="color:yellow;">router hooks</mark> or <mark style="color:yellow;">handle click events</mark>. This component should be converted to a client component.

#### b. Add the Client Directive

1. **Open the file** (e.g., a page inside `app/properties/[id]/page.jsx`).
2. **At the very top, add the following directive:**

   ```jsx
   "use client";
   ```
3. **Now you can use interactive hooks** (like state hooks, effects, and router hooks).

> **Note:** Without the `"use client"` directive, attempting to use hooks such as **`useRouter`** or **`useState`** will trigger an error, because these are only allowed in client components.

***

### 3. Introduction to Next.js Router Hooks

Next.js provides several router hooks under the <mark style="color:purple;">`next/navigation`</mark> module that let you handle routing dynamics efficiently. Here’s a quick overview:

#### a. `useRouter`

* **Purpose:** Enables you to navigate programmatically (e.g., redirecting users).
* **Usage Example:**

  ```jsx
  import { useRouter } from 'next/navigation';

  export default function MyComponent() {
    "use client"; // Required for client-side hooks

    const router = useRouter();

    function goHome() {
      router.push('/');
    }

    return (
      <button onClick={goHome}>
        Go Home
      </button>
    );
  }
  ```

#### b. `useParams`

* **Purpose:** Retrieve dynamic route parameters (e.g., `/properties/[id]`).
* **Usage Example:**

  ```jsx
  import { useParams } from 'next/navigation';

  export default function PropertyPage() {
    "use client"; // Because we're accessing dynamic routing in a client context

    const { id } = useParams();

    return (
      <div>
        <h1>Property ID: {id}</h1>
      </div>
    );
  }
  ```

#### c. `useSearchParams`

* **Purpose:** Access query parameters from the URL.
* **Usage Example:**

  ```jsx
  import { useSearchParams } from 'next/navigation';

  export default function SearchComponent() {
    "use client"; // Must be a client component

    const searchParams = useSearchParams();
    const name = searchParams.get('name');

    return (
      <div>
        <p>Search parameter 'name' is: {name}</p>
      </div>
    );
  }
  ```

#### d. `usePathname`

* **Purpose:** Obtain the current pathname from the URL.
* **Usage Example:**

  ```jsx
  import { usePathname } from 'next/navigation';

  export default function PathDisplay() {
    "use client";

    const pathname = usePathname();

    return (
      <div>
        <p>Current Path: {pathname}</p>
      </div>
    );
  }
  ```

***

### 4. Step-by-Step: Implementing <mark style="color:orange;">Router Hooks</mark> in Your Application

#### Step 1: Create a New Client Component

* **File:** <mark style="color:orange;">`app/properties/[id]/page.jsx`</mark>
* **Action:** Add `"`<mark style="color:red;">`use client`</mark>`";` at the top.

#### Step 2: Use `useRouter` for Navigation

* **Implementation:**

  ```jsx
  "use client";

  import { useRouter } from 'next/navigation';

  export default function PropertyPage() {
    const router = useRouter();

    function goToHome() {
      router.push('/');
    }

    return (
      <div>
        <h1>Property Details</h1>
        <button onClick={goToHome}>Go Home</button>
      </div>
    );
  }
  ```

#### Step 3: Retrieve Dynamic Route Parameter with `useParams`

* **Implementation:**

  ```jsx
  "use client";

  import { useParams } from 'next/navigation';

  export default function PropertyPage() {
    const { id } = useParams();

    return (
      <div>
        <h1>Property ID: {id}</h1>
      </div>
    );
  }
  ```

#### Step 4: Use `useSearchParams` to Get Query Parameters

* **Implementation:**

  ```jsx
  "use client";

  import { useSearchParams } from 'next/navigation';

  export default function PropertyPage() {
    const searchParams = useSearchParams();
    const ref = searchParams.get('ref');

    return (
      <div>
        <h1>Property Page</h1>
        {ref && <p>Referral Code: {ref}</p>}
      </div>
    );
  }
  ```

#### Step 5: Display the Current Pathname with `usePathname`

* **Implementation:**

  ```jsx
  "use client";

  import { usePathname } from 'next/navigation';

  export default function PropertyPage() {
    const pathname = usePathname();

    return (
      <div>
        <p>Current URL: {pathname}</p>
      </div>
    );
  }
  ```

***

### 5. Recap and Best Practices

* **Server Components vs. Client Components:**
  * Use **server components** for static rendering and secure data fetching.
  * Use **client components** (with `"use client"`) when interactivity and stateful behavior are needed.
* **Router Hooks:**
  * **`useRouter`** for programmatic navigation.
  * **`useParams`** for dynamic route parameters.
  * **`useSearchParams`** for accessing query parameters.
  * **`usePathname`** for retrieving the current path.
* **Practical Tip:**\
  When designing components, decide whether they need to be interactive. If so, mark them as client components; otherwise, lean on server components to optimize performance and security.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://reactjs.koida.tech/backend-frameworks-next.js/hands-on-practice-2/server-vs-client-components-and-router-hooks.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
