Patterns and Best Practices
React ve Next.js'de veri almak için önerilen birkaç kalıp ve en iyi uygulamalar vardır. Bu sayfa, en yaygın kalıplardan bazılarını ve bunların nasıl kullanılacağını ele alacaktır.
Fetching data on the server
Mümkün olduğunda, Sunucu Bileşenleri ile sunucudan veri almanızı öneririz. Bu size şunları sağlar:
- Arka uç veri kaynaklarına (ör. veritabanları) doğrudan erişime sahip olun.
- Erişim belirteçleri ve API anahtarları gibi hassas bilgilerin istemciye ifşa edilmesini önleyerek uygulamanızı daha güvenli tutun.
- Verileri alın ve aynı ortamda render edin. Bu, hem istemci ve sunucu arasındaki ileri geri iletişimi hem de istemcideki ana iş parçacığı üzerindeki çalışmayıazaltır.
- İstemcide birden fazla bireysel istek yerine tek bir gidiş-dönüş ile birden fazla veri getirme işlemi gerçekleştirin.
- İstemci-sunucu şelalelerini azaltın.
- Bölgenize bağlı olarak, veri getirme işlemi veri kaynağınıza daha yakın bir yerde de gerçekleşebilir, böylece gecikme süresi azalır ve performans artar.
Ardından, Sunucu Eylemleri ile verileri değiştirebilir veya güncelleyebilirsiniz.
Fetching data where it's needed
Bir ağaçtaki birden fazla bileşende aynı veriyi (örneğin mevcut kullanıcı) kullanmanız gerekiyorsa, verileri global olarak getirmeniz veya
bileşenler arasında prop'ları iletmeniz gerekmez. Bunun yerine, aynı veri için birden fazla istekte bulunmanın performans etkileri hakkında
endişelenmeden veriye ihtiyaç duyan bileşende fetch
veya React
cache
kullanabilirsiniz.
Bu mümkündür çünkü fetch
talepleri otomatik olarak not edilir.
İstek notu oluşturma hakkında daha
fazla bilgi edinin
Bilmekte fayda var: Bir üst düzen ile onun alt düzenleri arasında veri aktarımı mümkün olmadığından, bu durum düzenler için de geçerlidir.
Streaming
Streaming ve Suspense, kullanıcı arayüzünün render edilmiş birimlerini aşamalı olarak render etmenize ve istemciye aşamalı olarak aktarmanıza olanak tanıyan React özellikleridir.
Sunucu Bileşenleri ve iç içe düzenlerle, sayfanın özellikle veri gerektirmeyen kısımlarını anında oluşturabilir ve sayfanın veri getiren kısımları için bir yükleme durumu gösterebilirsiniz. Bu, kullanıcının sayfayla etkileşime geçmeden önce sayfanın tamamının yüklenmesini beklemek zorunda kalmayacağı anlamına gelir.


Akış ve Askıya Alma hakkında daha fazla bilgi edinmek için Yükleme Kullanıcı Arayüzü ve Akış ve Askıya Alma sayfalarına bakın.
Parallel and sequential data fetching
React bileşenleri içinde veri getirirken, iki veri getirme modelinin farkında olmanız gerekir: Paralel ve Sıralı.


- Sıralı veri getirme ile, bir rotadaki istekler birbirine bağımlıdır ve bu nedenle şelaleler oluşturur. Bu modeli istediğiniz durumlar olabilir çünkü bir getirme işlemi diğerinin sonucuna bağlıdır veya kaynakları korumak için bir sonraki getirme işleminden önce bir koşulun yerine getirilmesini istersiniz. Ancak bu davranış kasıtsız da olabilir ve daha uzun yükleme sürelerine yol açabilir.
- Paralel veri getirme ile, bir rotadaki istekler istekli olarak başlatılır ve aynı anda veri yüklenir. Bu, istemci-sunucu şelalelerini ve veri yüklemek için gereken toplam süreyi azaltır.
Sequential Data Fetching
İç içe geçmiş bileşenleriniz varsa ve her bileşen kendi verilerini getiriyorsa, bu veri istekleri farklıysa veri getirme işlemi sırayla gerçekleşir (bu, otomatik olarak memoize edildikleri için aynı veriler için yapılan istekler için geçerli değildir).
Örneğin, Playlists
bileşeni ancak Artist
bileşeni veri almayı tamamladıktan sonra veri
almaya başlayacaktır çünkü Playlists
, artistID
prop'una bağlıdır:
// ...
async function Playlists({ artistID }: { artistID: string }) {
// Wait for the playlists
const playlists = await getArtistPlaylists(artistID)
return (
<ul>
{playlists.map((playlist) => (
<li key={playlist.id}>{playlist.name}</li>
))}
</ul>
)
}
export default async function Page({
params: { username },
}: {
params: { username: string }
}) {
// Wait for the artist
const artist = await getArtist(username)
return (
<>
<h1>{artist.name}</h1>
<Suspense fallback={<div>Loading...</div>}>
<Playlists artistID={artist.id} />
</Suspense>
</>
)
}
Bu gibi durumlarda şunları kullanabilirsiniz
loading.js
(rota segmentleri için) veya
React <Suspense>
(iç içe geçmiş bileşenler için), React sonuçta akış yaparken anlık bir yükleme durumu göstermek için.
Bu, tüm rotanın veri getirme nedeniyle engellenmesini önleyecek ve kullanıcı sayfanın engellenmeyen bölümleriyle etkileşime girebilecektir.
Veri Taleplerini Engelleme:
Şelaleleri önlemek için alternatif bir yaklaşım, uygulamanızın kökünde global olarak veri getirmektir, ancak bu, verilerin yüklenmesi bitene kadar altındaki tüm rota segmentleri için oluşturmayı engelleyecektir. Bu, "ya hep ya hiç" veri getirme olarak tanımlanabilir. Ya sayfanız ya da uygulamanız için tüm verilere sahip olursunuz ya da hiçbirine sahip olmazsınız.
await
içeren tüm getirme istekleri, bir<Suspense>
sınırına sarılmadıkları veyaloading.js
kullanılmadıkları sürece, altındaki tüm ağacın oluşturulmasını ve veri getirilmesini engelleyecektir. Diğer bir alternatif ise paralel veri getirme veya ön yükleme modelini kullanmaktır.
Parallel Data Fetching
Verileri paralel olarak almak için istekleri, verileri kullanan bileşenlerin dışında tanımlayarak ve ardından bileşenin içinden çağırarak istekleri istekli bir şekilde başlatabilirsiniz. Bu, her iki isteği paralel olarak başlatarak zaman kazandırır, ancak kullanıcı her iki söz de çözümlenene kadar işlenen sonucu göremez.
Aşağıdaki örnekte, getArtist
ve getArtistAlbums
işlevleri
Page
bileşeninin dışında tanımlanır, ardından bileşenin içinde çağrılır ve her iki vaadin de çözümlenmesi
beklenir:
import Albums from './albums'
async function getArtist(username: string) {
const res = await fetch(`https://api.example.com/artist/${username}`)
return res.json()
}
async function getArtistAlbums(username: string) {
const res = await fetch(`https://api.example.com/artist/${username}/albums`)
return res.json()
}
export default async function Page({
params: { username },
}: {
params: { username: string }
}) {
// Initiate both requests in parallel
const artistData = getArtist(username)
const albumsData = getArtistAlbums(username)
// Wait for the promises to resolve
const [artist, albums] = await Promise.all([artistData, albumsData])
return (
<>
<h1>{artist.name}</h1>
<Albums list={albums}></Albums>
</>
)
}
Kullanıcı deneyimini iyileştirmek için, render çalışmasını bölmek ve sonucun bir kısmını mümkün olan en kısa sürede göstermek üzere bir Askıya Alma Sınırı ekleyebilirsiniz.
Preloading Data
Şelaleleri önlemenin bir başka yolu da ön yükleme modelini kullanmaktır. Paralel veri getirmeyi daha da optimize etmek için isteğe bağlı
olarak bir preload
işlevi oluşturabilirsiniz. Bu yaklaşımla, vaatleri prop olarak aktarmak zorunda kalmazsınız.
preload
işlevi de bir API değil, bir kalıp olduğu için herhangi bir isme sahip olabilir.
import { getItem } from '@/utils/get-item'
export const preload = (id: string) => {
// void evaluates the given expression and returns undefined
// https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/void
void getItem(id)
}
export default async function Item({ id }: { id: string }) {
const result = await getItem(id)
// ...
}
import Item, { preload, checkIsAvailable } from '@/components/Item'
export default async function Page({
params: { id },
}: {
params: { id: string }
}) {
// starting loading item data
preload(id)
// perform another asynchronous task
const isAvailable = await checkIsAvailable()
return isAvailable ? <Item id={id} /> : null
}
Using React cache
, server-only
, and the Preload Pattern
Uygulamanızın tamamında kullanılabilecek bir veri getirme yardımcı programı oluşturmak için cache
işlevini,
preload
kalıbını ve server-only
paketini birleştirebilirsiniz.
import { cache } from 'react'
import 'server-only'
export const preload = (id: string) => {
void getItem(id)
}
export const getItem = cache(async (id: string) => {
// ...
})
Bu yaklaşımla, istekli bir şekilde veri getirebilir, yanıtları önbelleğe alabilir ve bu veri getirme işleminin yalnızca sunucuda gerçekleşmesini garanti edebilirsiniz.
utils/get-item
dışa aktarımları, bir öğenin verilerinin ne zaman alınacağını kontrol etmelerini sağlamak için
Düzenler, Sayfalar veya diğer bileşenler tarafından kullanılabilir.
Bilmekte fayda var:
- Sunucu veri getirme işlevlerinin istemcide asla kullanılmadığından emin olmak için
server-only
paketinikullanmanızı öneririz.
Preventing sensitive data from being exposed to the client
React'in taint API'lerini kullanmanızı öneririz,
taintObjectReference
ve
taintUniqueValue
tüm nesne örneklerinin veya hassas değerlerin istemciye aktarılmasını önlemek için.
Uygulamanızda lekelenmeyi etkinleştirmek için Next.js Config experimental.taint
seçeneğini
true
olarak ayarlayın:
module.exports = {
experimental: {
taint: true,
},
}
Ardından, lekelemek istediğiniz nesneyi veya değeri experimental_taintObjectReference
veya
experimental_taintUniqueValue
işlevlerine aktarın:
import { queryDataFromDB } from './api'
import {
experimental_taintObjectReference,
experimental_taintUniqueValue,
} from 'react'
export async function getUserData() {
const data = await queryDataFromDB()
experimental_taintObjectReference(
'Do not pass the whole user object to the client',
data
)
experimental_taintUniqueValue(
"Do not pass the user's phone number to the client",
data,
data.phoneNumber
)
return data
}
import { getUserData } from './data'
export async function Page() {
const userData = getUserData()
return (
<ClientComponent
user={userData} // this will cause an error because of taintObjectReference
phoneNumber={userData.phoneNumber} // this will cause an error because of taintUniqueValue
/>
)
}
Güvenlik ve Sunucu Eylemleri hakkında daha fazla bilgi için .