'use client'
'use client'
istemcide hangi kodun çalışacağını işaretlemenizi sağlar.
Başvuru Dokümanı
'use client'
Modülü ve geçişli bağımlılıklarını istemci kodu olarak işaretlemek için bir dosyanın başına 'use client'
ekleyin.
'use client';
import { useState } from 'react';
import { formatDate } from './formatters';
import Button from './button';
export default function RichTextEditor({ timestamp, text }) {
const date = formatDate(timestamp);
// ...
const editButton = <Button />;
// ...
}
Bir Sunucu Bileşeninden 'use client'
ile işaretlenmiş bir dosya içe aktarıldığında, uyumlu paketleyiciler modül içe aktarımını sunucu tarafından çalıştırılan ve istemci tarafından çalıştırılan kod arasında bir sınır olarak değerlendirecektir.
RichTextEditor
bağımlılıkları olarak, formatDate
ve Button
da modüllerinin bir 'use client'
yönergesi içerip içermediğine bakılmaksızın istemcide değerlendirilecektir. Tek bir modülün sunucu kodundan içe aktarıldığında sunucuda, istemci kodundan içe aktarıldığında ise istemcide değerlendirilebileceğini unutmayın.
Uyarılar
'use client'
bir dosyanın en başında, tüm içe aktarmaların veya diğer kodların üzerinde olmalıdır (yorumlarda sorun yoktur). Tek ya da çift tırnakla yazılmalı, ancak ters tırnak kullanılmamalıdır.- Bir
'use client'
modülü istemci tarafından oluşturulan başka bir modülden içe aktarıldığında, direktifin hiçbir etkisi yoktur. - Bir bileşen modülü
'use client'
yönergesi içerdiğinde, bu bileşenin her türlü kullanımının bir İstemci Bileşeni olacağı garanti edilir. Ancak bir bileşen'use client'
yönergesine sahip olmasa bile istemci üzerinde değerlendirilebilir.- Bir bileşen kullanımı,
'use client'
yönergesine sahip bir modülde tanımlanmışsa veya'use client'
yönergesi içeren bir modülün geçişli bağımlılığı ise İstemci Bileşeni olarak kabul edilir. Aksi takdirde, bir Sunucu Bileşenidir.
- Bir bileşen kullanımı,
- İstemci değerlendirmesi için işaretlenen kod bileşenlerle sınırlı değildir. İstemci modülü alt ağacının bir parçası olan tüm kodlar istemciye gönderilir ve istemci tarafından çalıştırılır.
- Sunucu tarafından değerlendirilen bir modül, bir
'use client'
modülünden değerleri içe aktardığında, değerler ya bir React bileşeni olmalı ya da bir İstemci Bileşenine aktarılmak üzere desteklenen serileştirilebilir prop değerleri olmalıdır. Diğer kullanım durumları bir istisna oluşturur.
'use client'
istemci kodunu nasıl işaretler?
Bir React uygulamasında bileşenler genellikle ayrı dosyalara veya modüllere ayrılır.
React Sunucu Bileşenleri kullanan uygulamalar için, uygulama varsayılan olarak sunucu tarafından oluşturulur. 'use client'
, modül bağımlılık ağacında bir sunucu-istemci sınırı getirerek etkin bir şekilde İstemci modüllerinin bir alt ağacını oluşturur.
Bunu daha iyi açıklamak için aşağıdaki React Sunucu Bileşenleri uygulamasını düşünün.
import FancyText from './FancyText'; import InspirationGenerator from './InspirationGenerator'; import Copyright from './Copyright'; export default function App() { return ( <> <FancyText title text="İlham Alma Uygulaması" /> <InspirationGenerator> <Copyright year={2004} /> </InspirationGenerator> </> ); }
Bu örnek uygulamanın modül bağımlılık ağacında, InspirationGenerator.js
içindeki 'use client'
yönergesi bu modülü ve tüm geçişli bağımlılıklarını İstemci modülleri olarak işaretler. InspirationGenerator.js
ile başlayan alt ağaç artık İstemci modülleri olarak işaretlenmiştir.
Render sırasında, framework root bileşeni sunucuda render edecek ve render ağacı üzerinden devam ederek istemci tarafından işaretlenmiş koddan alınan herhangi bir kodu değerlendirmeyi tercih etmeyecektir.
Render ağacının sunucu tarafından render edilen kısmı daha sonra istemciye gönderilir. İstemci, istemci kodunu indirdikten sonra ağacın geri kalanını oluşturmayı tamamlar.
Aşağıdaki tanımları tanıtıyoruz:
- İstemci Bileşenleri bir render ağacında bulunan ve istemcide render edilen bileşenlerdir
- Sunucu Bileşenleri bir render ağacında bulunan ve sunucuda render edilen bileşenlerdir.
Örnek uygulama üzerinde çalışıldığında, App
, FancyText
ve Copyright
sunucu tarafından oluşturulur ve Sunucu Bileşenleri olarak kabul edilir. InspirationGenerator.js
ve onun geçişli bağımlılıkları istemci kodu olarak işaretlendiğinden, InspirationGenerator
bileşeni ve onun alt bileşeni FancyText
İstemci Bileşenleridir.
Derinlemesine İnceleme
Yukarıdaki tanımlara göre, FancyText
bileşeni hem Sunucu hem de İstemci Bileşenidir, bu nasıl olabilir?
Öncelikle “bileşen” teriminin çok kesin olmadığını açıklığa kavuşturalım. Burada “bileşen” kelimesinin anlaşılabileceği sadece iki yol vardır:
- Bir “bileşen” bir bileşen tanımı anlamına gelebilir. Çoğu durumda bu bir fonksiyon olacaktır.
// Bu bir bileşenin tanımıdır
function MyComponent() {
return <p>My Component</p>
}
- Bir “bileşen”, tanımının bir bileşen kullanımına da atıfta bulunabilir.
import MyComponent from './MyComponent';
function App() {
// Bu bir bileşenin kullanımıdır
return <MyComponent />;
}
Kavramları açıklarken çoğu zaman kesin olmamak önemli değildir, ancak bu durumda önemlidir.
Sunucu veya İstemci Bileşenleri hakkında konuştuğumuzda, bileşen kullanımlarına atıfta bulunuyoruz.
- Bileşen
'use client'
yönergesine sahip bir modülde tanımlanmışsa veya bileşen bir İstemci Bileşeni içinde içe aktarılmış ve çağrılmışsa, bileşen kullanımı bir İstemci Bileşenidir. - Aksi takdirde, bileşen kullanımı bir Sunucu Bileşenidir.
FancyText
sorusuna geri dönersek, bileşen tanımının bir 'use client'
yönergesine sahip olmadığını ve iki kullanımı olduğunu görüyoruz.
FancyText
’in App
’in bir alt öğesi olarak kullanılması, bu kullanımı bir Sunucu Bileşeni olarak işaretler. FancyText
içe aktarıldığında ve InspirationGenerator
altında çağrıldığında, InspirationGenerator
bir 'use client'
yönergesi içerdiğinden, FancyText
kullanımı bir İstemci Bileşenidir.
FancyText
için bileşen tanımının hem sunucuda değerlendirileceği hem de İstemci Bileşeni kullanımını oluşturmak için istemci tarafından indirileceği anlamına gelir.
Derinlemesine İnceleme
Copyright
, InspirationGenerator
İstemci Bileşeninin bir çocuğu olarak işlendiğinden, bunun bir Sunucu Bileşeni olması sizi şaşırtabilir.
'use client'
’ın sunucu ve istemci kodu arasındaki sınırı render ağacında değil modül bağımlılık ağacında tanımladığını hatırlayın.
Modül bağımlılık ağacında, App.js
modülünün Copyright.js
modülünden Copyright
modülünü içe aktardığını ve çağırdığını görüyoruz. Copyright.js
bir 'use client'
direktifi içermediğinden, bileşen kullanımı sunucuda oluşturulur. Root bileşen olduğu için App
sunucuda oluşturulur.
JSX’i prop olarak geçirebildiğiniz için İstemci Bileşenleri Sunucu Bileşenlerini oluşturabilir. Bu durumda, InspirationGenerator
children olarak Copyright
alır. Ancak InspirationGenerator
modülü Copyright
modülünü asla doğrudan içe aktarmaz veya bileşeni çağırmaz, bunların hepsi App
tarafından yapılır. Aslında InspirationGenerator
oluşturmaya başlamadan önce Copyright
bileşeni tamamen çalıştırılır.
Buradan çıkarılacak sonuç, bileşenler arasındaki üst eleman-alt eleman render ilişkisinin aynı render ortamını garanti etmediğidir.
'use client'
ne zaman kullanılır?
'use client'
ile bileşenlerin ne zaman İstemci Bileşeni olduğunu belirleyebilirsiniz. Sunucu Bileşenleri varsayılan olduğundan burada bir şeyi ne zaman istemci tarafından işlenmiş olarak işaretlemeniz gerektiğini belirlemek için Sunucu Bileşenlerinin avantajları ve sınırlamalarına kısa bir genel bakış yer almaktadır.
Basit olması için Sunucu Bileşenlerinden bahsediyoruz, ancak aynı ilkeler uygulamanızdaki sunucuda çalışan tüm kodlar için geçerlidir.
Sunucu Bileşenlerinin Avantajları
- Sunucu Bileşenleri, istemci tarafından gönderilen ve çalıştırılan kod miktarını azaltabilir. Yalnızca İstemci modülleri paketlenir ve istemci tarafından değerlendirilir.
- Sunucu Bileşenleri sunucu üzerinde çalışmaktan yararlanır. Yerel dosya sistemine erişebilirler ve veri getirme ve ağ istekleri için düşük gecikme yaşayabilirler.
Sunucu Bileşenlerinin Sınırlamaları
- Olay yöneticilerinin bir istemci tarafından kaydedilmesi ve tetiklenmesi gerektiğinden Sunucu Bileşenleri etkileşimi destekleyemez.
- Örneğin,
onClick
gibi olay yöneticileri yalnızca İstemci Bileşenlerinde tanımlanabilir.
- Örneğin,
- Sunucu Bileşenleri çoğu Hook’ları kullanamaz.
- Sunucu Bileşenleri işlendiğinde, çıktıları esasen istemcinin işlemesi için bileşenlerin bir listesidir. Sunucu Bileşenleri render işleminden sonra bellekte kalıcı değildir ve kendi state’lerine sahip olamazlar.
Sunucu Bileşenleri tarafından döndürülen serileştirilebilir türler
Tüm React uygulamalarında olduğu gibi, üst bileşenler alt bileşenlere veri aktarır. Farklı ortamlarda işlendikleri için, bir Sunucu Bileşeninden bir İstemci Bileşenine veri aktarmak ekstra dikkat gerektirir.
Bir Sunucu Bileşeninden İstemci Bileşenine aktarılan prop değerleri serileştirilebilir olmalıdır.
Serileştirilebilir prop’lar şunları içerir:
- Primitives
- Serileştirilebilir değerler içeren yinelenebilir dosyalar
- Date
- Plain objects: those created with object initializers, with serializable properties
- Functions that are Server Functions
- Client or Server Component elements (JSX)
- Promises
Özellikle, bunlar desteklenmemektedir:
- İstemci işaretli modüllerden dışa aktarılmayan veya
'use server'
ile işaretlenmeyen Functions - Classes
- Herhangi bir sınıfın örneği olan nesneler (belirtilen yerleşikler dışında) veya null prototype nesneler
- Global olarak kaydedilmemiş semboller, örn.
Symbol('my new symbol')
Kullanım
Etkileşim ve state ile inşa etme
'use client'; import { useState } from 'react'; export default function Counter({initialValue = 0}) { const [countValue, setCountValue] = useState(initialValue); const increment = () => setCountValue(countValue + 1); const decrement = () => setCountValue(countValue - 1); return ( <> <h2>Sayı: {countValue}</h2> <button onClick={increment}>+1</button> <button onClick={decrement}>-1</button> </> ); }
Counter
değeri artırmak ya da azaltmak için hem useState
Hook’una hem de olay yöneticilerine ihtiyaç duyduğundan, bu bileşen bir İstemci Bileşeni olmalıdır ve en üstte bir 'use client'
yönergesi gerektirecektir.
Buna karşılık etkileşim olmadan kullanıcı arayüzü oluşturan bir bileşenin İstemci Bileşeni olması gerekmez.
import { readFile } from 'node:fs/promises';
import Counter from './Counter';
export default async function CounterContainer() {
const initialValue = await readFile('/path/to/counter_value');
return <Counter initialValue={initialValue} />
}
Örneğin Counter
ın üst bileşeni olan CounterContainer
etkileşimli olmadığı ve state kullanmadığı için 'use client'
gerektirmez. Ayrıca CounterContainer
bir Sunucu Bileşeni olmalıdır, çünkü sunucudaki yerel dosya sisteminden okuma yapar. Bu da yalnızca bir Sunucu Bileşeninde mümkündür.
Sunucu veya istemciye özel herhangi bir özellik kullanmayan ve nerede işlendiklerinden bağımsız olabilen bileşenler de vardır. Daha önceki örneğimizde, FancyText
böyle bir bileşendir.
export default function FancyText({title, text}) {
return title
? <h1 className='fancy title'>{text}</h1>
: <h3 className='fancy cursive'>{text}</h3>
}
Bu durumda 'use client'
yönergesini eklemiyoruz, bu da FancyText
’in output’unun (kaynak kodu yerine) bir Sunucu Bileşeninden başvurulduğunda tarayıcıya gönderilmesine neden oluyor. Daha önceki Inspirations uygulaması örneğinde gösterildiği gibi FancyText
içe aktarıldığı ve kullanıldığı yere bağlı olarak hem Sunucu hem de İstemci Bileşeni olarak kullanılır.
Ancak FancyText
in HTML çıktısı kaynak koduna (bağımlılıklar dahil) göre büyükse, onu her zaman bir İstemci Bileşeni olmaya zorlamak daha verimli olabilir. Uzun bir SVG path’i döndüren bileşenler, bir bileşeni İstemci Bileşeni olmaya zorlamanın daha verimli olabileceği bir durumdur.
İstemci API’lerini kullanma
React uygulamanız, diğerlerinin yanı sıra tarayıcının web depolama, ses ve video işleme ve cihaz donanımı için API’leri gibi istemciye özel API’ler kullanabilir.
Bu örnekte bileşen bir canvas
öğesini işlemek için DOM API’lerini kullanır. Bu API’ler yalnızca tarayıcıda kullanılabildiğinden, İstemci Bileşeni olarak işaretlenmelidir.
'use client';
import {useRef, useEffect} from 'react';
export default function Circle() {
const ref = useRef(null);
useLayoutEffect(() => {
const canvas = ref.current;
const context = canvas.getContext('2d');
context.reset();
context.beginPath();
context.arc(100, 75, 50, 0, 2 * Math.PI);
context.stroke();
});
return <canvas ref={ref} />;
}
Üçüncü taraf kütüphaneleri kullanma
Genellikle bir React uygulamasında yaygın kullanıcı arayüzü modellerini veya mantığını işlemek için üçüncü taraf kütüphanelerden yararlanırsınız.
Bu kütüphaneler bileşen Hook’larına veya istemci API’lerine dayanabilir. Aşağıdaki React API’lerinden herhangi birini kullanan üçüncü taraf bileşenleri istemci üzerinde çalışmalıdır:
- createContext
react
vereact-dom
Hooks,use
veuseId
hariç- forwardRef
- memo
- startTransition
- İstemci API’leri kullanıyorlarsa, örneğin DOM ekleme veya yerel platform görünümleri
Bu kütüphaneler React Server Components ile uyumlu olacak şekilde güncelleştirildiyse, kendi ’`‘use client’ işaretçilerini zaten içerecek ve bunları doğrudan Sunucu Bileşenlerinizden kullanmanıza olanak tanıyacaktır. Bir kütüphane güncellenmemişse veya bir bileşenin yalnızca istemcide belirtilebilen olay yöneticileri gibi desteklere ihtiyacı varsa, üçüncü taraf İstemci Bileşeni ile kullanmak istediğiniz Sunucu Bileşeniniz arasına kendi İstemci Bileşeni dosyanızı eklemeniz gerekebilir.