جاري التحميل...
جاري التحميل...
use cache directive، cacheLife، cacheTag، استراتيجيات التخزين
Next.js 16 يقدم نموذج تخزين مؤقت جديد تماماً. لا شيء يُخزّن مؤقتاً إلا إذا طلبته صراحةً باستخدام 'use cache'.
كل مكون ودالة تنفذ في كل مرة إلا إذا أضفت 'use cache'.
أضف 'use cache' في أعلى دالة أو مكون لتمكين التخزين المؤقت. يمكنك التخزين على مستوى الدالة أو المكون أو مع وسوم محددة.
'use cache' — تخزين مؤقت للقيمة المُعادة من الدالة.'use cache' مع وسوم — تخزين مؤقت مع وسوم للإبطال المستهدف.ما هو سلوك التخزين المؤقت الافتراضي في Next.js 16؟
كيف تخزّن دالة مؤقتاً في Next.js 16؟
أضف 'use cache' إلى المكونات واختبر سلوك التخزين المؤقت مع سيناريوهات مختلفة.
الحل:
// الحل الكامل
// 1. ملف lib/products.js
import { cacheLife, cacheTag } from "next/cache";
import { db } from "./database";
export async function getProducts(categoryId) {
"use cache";
cacheLife("hours");
cacheTag("products");
console.log("جلب المنتجات من قاعدة البيانات");
return await db.products.findMany({
where: categoryId ? { categoryId } : {},
orderBy: { createdAt: "desc" },
});
}
export async function getProduct(id) {
"use cache";
cacheLife({ revalidate: 600 }); // 10 دقائق
cacheTag(`product-${id}`);
console.log(`جلب المنتج ${id} من قاعدة البيانات`);
return await db.products.findUnique({ where: { id } });
}
export async function getCategories() {
"use cache";
cacheLife("days");
cacheTag("categories");
return await db.categories.findMany();
}
// 2. ملف app/actions.js
"use server";
import { revalidateTag } from "next/cache";
import { redirect } from "next/navigation";
export async function createProduct(prevState, formData) {
const name = formData.get("name")?.trim();
const price = Number(formData.get("price"));
const categoryId = formData.get("categoryId");
if (!name || price <= 0) {
return { error: "بيانات غير صحيحة" };
}
await db.products.create({
data: { name, price, categoryId },
});
revalidateTag("products");
return { error: null };
}
export async function deleteProduct(productId) {
await db.products.delete({ where: { id: productId } });
revalidateTag("products");
revalidateTag(`product-${productId}`);
redirect("/products");
}
// 3. ملف app/products/page.js
import { Suspense } from "react";
import { getProducts, getCategories } from "@/lib/products";
import ProductForm from "@/components/ProductForm";
import ProductList from "@/components/ProductList";
export default async function ProductsPage() {
const [products, categories] = await Promise.all([
getProducts(),
getCategories(),
]);
return (
<div className="p-8">
<h1 className="text-3xl font-bold mb-8">المنتجات ({products.length})</h1>
<ProductForm categories={categories} />
<Suspense fallback={<p>جاري تحميل المنتجات...</p>}>
<ProductList products={products} />
</Suspense>
</div>
);
}تعليمة "use cache":
// تخزين مؤقت على مستوى الدالة
async function getProducts() {
"use cache";
cacheLife("hours");
cacheTag("products");
return await db.products.findMany();
}
// تخزين مؤقت على مستوى الملف
"use cache";
async function Page() {
const data = await fetchData();
return <div>{data}</div>;
}أنماط cacheLife:
"seconds" - 30 ثانية (بيانات مباشرة)"minutes" - 5 دقائق (بيانات عادية)"hours" - ساعة واحدة (شبه ثابتة)"days" - يوم واحد (بيانات ثابتة)"max" - 30 يوماً (ثابتة جداً)أنواع التخزين المؤقت:
"use cache" - في الذاكرة (الأسرع)"use cache: remote" - خارجي (Redis)"use cache: private" - لكل طلب (مخصص للمستخدم)الإبطال:
import { revalidateTag, updateTag }
from "next/cache";
revalidateTag("products");
updateTag("products");كيف يعمل caching في Next.js؟
الإجابة:
يُخزن نتائج fetch تلقائياً. استخدم revalidate للتحديث.
ما هو revalidation؟
الإجابة:
تحديث البيانات المخزنة بعد فترة أو عند الطلب.
استخدم unstable_cache
لتخزين نتائج دوال مكلفة