React Server Components و Next.js
Server vs Client Components
في Next.js 16، كل المكوّنات هي Server Components افتراضياً. أضف "use client" فقط عندما تحتاج ميزات المتصفح.
| الميزة | Server Component | Client Component |
|---|---|---|
useState, useEffect | غير متاح | متاح |
onClick, onChange | غير متاح | متاح |
localStorage, window | غير متاح | متاح |
| جلب البيانات (DB/API) | متاح مباشرة | عن طريق use() أو React Query |
| حجم JS المرسل | صفر | يُضمّن في bundle العميل |
| الوصول للمفاتيح السرية | آمن | غير آمن |
استخدام "use client"
"use client";
import { useState } from "react";
export function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>العدد: {count}</p>
<button onClick={() => setCount(count + 1)}>+</button>
</div>
);
}
استخدام "use server" (Server Actions)
// app/actions.ts
"use server";
export async function createUser(formData: FormData) {
const http = new HttpClient("/api");
const user = await http.post("/users", {
name: formData.get("name"),
email: formData.get("email"),
});
return user;
}
جلب البيانات في Server Component
// app/users/page.tsx
import { HttpClient, UserDTO } from "./lib/react-base-repository";
// هذا المكوّن يعمل على الخادم فقط — لا يصل أبداً للعميل
async function UsersPage() {
const http = new HttpClient("https://api.example.com");
const users: UserDTO[] = await http.get("/users");
return (
<ul>
{users.map((u) => (
<li key={u.id}>{u.name} — {u.email}</li>
))}
</ul>
);
}
التركيب (Composition) الصحيح
اللوحة (Server Component)
├── <Header /> (Server — بيانات من DB)
├── <Suspense>
│ └── <Profile /> (Server — بيانات متدفقة)
└── <Counter> (Client — "use client")
└── {children} (Server Component كلوحة فرعية)
ملاحظات إصدار Next.js 16
paramsوsearchParamsأصبحت async — استخدمawait paramsmiddleware.tsأُعيدت تسميتها إلىproxy.tsfetchلا يُخزَّن مؤقتاً افتراضياً — استخدمuse cacheأوReact.cache()- Turbopack هو المشغّل الافتراضي
next/image: الصور المحلية تحتاجimages.localPatterns.search