React.cache()
Kısaca: Eşzamansız bir çağrının (örneğin bir veri tabanı sorgusunun) sonucunu tek bir istek içinde önbelleğe alan bir React işlevi — aynı istek içinde aynı işlevi aynı argümanlarla birkaç kez çağırırsan, asıl iş yalnızca bir kez çalışır.
Biraz daha ayrıntılı: Önemli: önbellek yalnızca tek bir sunucu isteği süresince geçerlidir, farklı kullanıcılar veya istekler arasında değil (genel/paylaşılan önbellek yok). Tipik kullanım durumu: getCurrentUser() gibi bir işlev bir sayfa görüntülemesi sırasında birkaç bağımsız yerde sık çağrılır (örneğin bir kez üst bilgide, bir kez sayfanın kendisinde) — React.cache() olmadan bu, tek bir sayfa görüntülemesi başına birkaç özdeş veri tabanı gidiş-dönüşü demektir.
Bizim bağlamımız: Bu, Emzett’in Vercel sunucusunun özellikle birkaç eşzamanlı ziyaretçiyle ara sıra çökmesinin makul ana nedeniydi — getCurrentUser()/getSetting() 12 sayfanın 11’inde iki kez çalışıyordu, her biri tam bir veri tabanı gidiş-dönüşüyle. React.cache() ile sarıldığında iki çağrı — canlı doğrulandı — tek bir gerçek veri tabanı erişimine dönüştü.
Ayrıntılı
Nasıl çalışır: React.cache() istek başına (teknik olarak: React sunucu işleme geçişi başına) hangi işlevin hangi argümanlarla zaten çağrıldığını hatırlar ve ikinci özdeş çağrıda işlevi yeniden çalıştırmak yerine zaten hesaplanmış sonucu döndürür:
import { cache } from "react";
export const getCurrentUser = cache(async () => {
const session = await getSession();
if (!session) return null;
return db.query.users.findFirst({ where: eq(users.id, session.userId) });
});Kulağa benzer gelen ama başka bir şey yapan diğer Next.js önbellekleme mekanizmalarından ayırt etmek önemlidir: fetch() önbelleklemesi ve cache tag’leri/revalidateTag verileri sayfalar ARASINDA ve istekler ARASINDA önbelleğe alır (açıkça geçersiz kılınana kadar), oysa React.cache() açıkça YALNIZCA tek bir isteğin yaşam döngüsü içinde tekilleştirir ve sonra atılır — bir sonraki kullanıcı veya bir sonraki sayfa görüntülemesi için işlev yine tamamen normal çalışır.
Tekilleştirme neden farklı verilerde çalışmaz
React.cache() “özdeş çağrıları” geçirilen argümanları karşılaştırarak tanır (bir memoizasyon anahtarına benzer). Aynı işlevi FARKLI argümanlarla çağırırsan tekilleştirme uygulanmaz — her benzersiz argüman kümesi istek başına bir kez çalışır:
await getUserById("abc"); // gerçekten çalışır
await getUserById("abc"); // önbellekten, veri tabanı erişimi yok
await getUserById("xyz"); // farklı argümanlar -> yine gerçekten çalışırBu genellikle tam olarak istenen davranıştır, ancak sık bir yanlış anlama: React.cache()’in istekteki HER veri tabanı erişimini birleştirdiğini varsayan biri, biraz farklı iki çağrı (örneğin bir kez isteğe bağlı bir parametreyle, bir kez onsuz) yine iki gerçek sorguyu tetiklediğinde şaşırır.
useMemo’dan farkı
useMemo istemci tarafındadır (tarayıcıda, bileşen başına, yeniden işlemeler boyunca çalışır) ve eşzamanlı hesaplamalar içindir — React.cache() yalnızca sunucuya özgüdür, eşzamansız veri erişimi için yapılmıştır ve yalnızca tek bir bileşen içinde değil, bir isteğin bileşen ağacının tüm genişliğinde tekilleştirir. İkisi farklı sorunları çözer ve birbirinin yerine kullanılamaz.
Ayrıca bak: Neon, Neon Auto-Suspend, Cache tag’leri/revalidateTag