use, Promise veya context gibi bir kaynağın değerini okumanıza olanak sağlayan bir React API’ıdır.

const value = use(resource);

Referans

use(resource)

Promise veya context gibi kaynakların değerini okumak için bileşeninizde use API’ını çağırabilirsiniz.

import { use } from 'react';

function MessageComponent({ messagePromise }) {
const message = use(messagePromise);
const theme = use(ThemeContext);
// ...

Diğer React Hook’ların aksine, Döngülerin ve if gibi koşullu ifadeler içerisinde use kullanılabilir. Diğer React Hook’lar gibi, use kullanan fonksiyon bir Bileşen veya Hook olmalıdır.

Bir Pomise ile çağırıldığında; use API, Suspense ve hata sınırları ile entegre olur. use’a iletilen Promise beklenirken, use çağrısı yapan bileşen askıya alınır. Eğer use çağrısı yapan bileşen Suspense içerisine alınırsa yedek görünüm görüntülenecektir. Promise çözümlendiğinde ise; Suspense yedek görünümü, use API’ı tarafından döndürülen değerleri kullanarak oluşturulan bileşenler ile yer değiştirir. Eğer use’a iletilen Promise reddedilir ise, en yakındaki Hata Sınırının yedek görünümü görüntülenecektir.

Bir Promise ile çağrıldığında, use API’si Suspense ve Error Boundaries ile entegre çalışır. use çağrısı yapan bileşen, use fonksiyonuna iletilen Promise beklemede (pending) olduğu sürece askıya alınır (suspend olur). Eğer bu bileşen bir Suspense boundary içine sarılmışsa, fallback içerik gösterilir. Promise çözümlendiğinde (resolved), Suspense fallback kaldırılır ve use API’si tarafından döndürülen veriyi kullanan bileşenler render edilir. Eğer use fonksiyonuna iletilen Promise reddedilirse (rejected), en yakın Error Boundary’nin fallback içeriği gösterilir.

Parametreler

  • resource: Bu, bir değeri okumak istediğiniz verinin kaynağıdır. Kaynak, Promise ya da context olabilir.

Dönüş Değerleri

use API, Promise ya da context gibi bir kaynaktan çözümlenen veriyi döndürür.

The use API returns the value that was read from the resource like the resolved value of a Promise or context.

Caveats

  • use API’si bir Bileşen veya Hook içinde çağrılmalıdır.
  • Sunucu Bileşenleri içinde veri çekerken, use yerine async ve await kullanmayı tercih edin. async ve await, await çağrıldığında render’a başlar, oysa use veri çözümlandıktan sonra bileşeni yeniden render eder.
  • Sunucu Bileşenleri içinde Promise’ler oluşturmayı ve bunları İstemci Bileşenleri içine iletmeyi, İstemci Bileşenleri içinde Promise’ler oluşturmaya tercih edin. Client Bileşenleri içinde oluşturulan Promise’ler her render işleminde yeniden oluşturulur. Sunucu Bileşenlerin’den İstemci Bileşenleri’e geçirilen Promise’ler yeniden render’lar arasında sabittir. Bu örneğe bakın.

Kullanım

use ile context okumak

use’a context aktarıldığında, useContext gibi çalışacaktır. useContext bileşende üst seviye olarak çağırılmak zorundayken; use ifadesi, if gibi koşullu ifadelerin ve for gibi döngü ifadelerinin içerisinde kullanılabilir. Çok daha esnek kullanılabildiğinden dolayı use ifadesi, useContext yerine tercih edilebilir.

import { use } from 'react';

function Button() {
const theme = use(ThemeContext);
// ...

use, içerisine aktarmış olduğunuz context’in context değerini döndürür. Context değerini belirlemek için React, bileşen ağacını arar ve ilgili context için en yakın context sağlayıcısını bulur.

Bir Button’a context aktarmak için, onu veya üst bileşenlerinden herhangi birini Context sağlayıcısının içerisine ekleyin.

function MyPage() {
return (
<ThemeContext value="dark">
<Form />
</ThemeContext>
);
}

function Form() {
// ... içerideki button'ları yeniden oluşturur ...
}

Sağlayıcı ile Button arasında kaç katman olduğu önemli değildir. Form içerisinde herhangi bir yerdeki Button, use(ThemeContext)’i çağırdığında değer olarak "dark" alacaktır.

useContext aksine; use, döngüler ve if gibi koşullu ifadeler içerisinde kullanılabilir.

function HorizontalRule({ show }) {
if (show) {
const theme = use(ThemeContext);
return <hr className={theme} />;
}
return false;
}

use, bir if ifadesinin içerisinde çağırılır. Bu size Context verilerini koşullu olarak okuma imkanı verir.

Tuzak

use(context), useContext gibi her zaman çağırıldığı bileşenin üstündeki en yakın context sağlayıcısını arar. Yukarı doğru arama yapar ve use(context)’i çağırdığınız bileşendeki context sağlayıcılarını dikkate almaz.

import { createContext, use } from 'react';

const ThemeContext = createContext(null);

export default function MyApp() {
  return (
    <ThemeContext value="dark">
      <Form />
    </ThemeContext>
  )
}

function Form() {
  return (
    <Panel title="Hoşgeldin">
      <Button show={true}>Kayıt ol</Button>
      <Button show={false}>Giriş Yap</Button>
    </Panel>
  );
}

function Panel({ title, children }) {
  const theme = use(ThemeContext);
  const className = 'panel-' + theme;
  return (
    <section className={className}>
      <h1>{title}</h1>
      {children}
    </section>
  )
}

function Button({ show, children }) {
  if (show) {
    const theme = use(ThemeContext);
    const className = 'button-' + theme;
    return (
      <button className={className}>
        {children}
      </button>
    );
  }
  return false
}

Sunucudan istemciye veri aktarımı

Sunucudan gelen veri; Sunucu Bileşeni’nden İstemci Bileşeni’ne Promise biçiminde prop olarak aktarılır.

import { fetchMessage } from './lib.js';
import { Message } from './message.js';

export default function App() {
const messagePromise = fetchMessage();
return (
<Suspense fallback={<p>Mesaj bekleniyor...</p>}>
<Message messagePromise={messagePromise} />
</Suspense>
);
}

İstemci Bileşeni prop olarak iletilen Promise’i alır ve use API’ına ileterek kullanır. Bu yöntem Sunucu Bileşeni içerisinde oluşturulan Promise’ten alınan verinin İstemci Bileşeni tarafından okunmasına olanak tanır.

// message.js
'use client';

import { use } from 'react';

export function Message({ messagePromise }) {
const messageContent = use(messagePromise);
return <p>Aktarılan Mesaj: {messageContent}</p>;
}

Message bir Suspense içerisinde olduğu için Promise çözümleninceye kadar yedek görünüm görüntülenecektir. Promise çözümlendiğinde değer use API tarafından okunacak ve Message bileşeni Suspense’in yedek görünüm ile yer değiştirecektir.

"use client";

import { use, Suspense } from "react";

function Message({ messagePromise }) {
  const messageContent = use(messagePromise);
  return <p>Aktarılan Mesaj: {messageContent}</p>;
}

export function MessageContainer({ messagePromise }) {
  return (
    <Suspense fallback={<p>⌛Mesaj Yükleniyor...</p>}>
      <Message messagePromise={messagePromise} />
    </Suspense>
  );
}

Not

Sunucu Bileşeni’nden İstemci Bileşeni’ne Promise aktarıldığında çözümlenen değer sunucu ile istemci arasından geçmesi için serileştirilebilir olması gerekir. Fonksiyonlar gibi veri türleri serileştirilemezler ve Promise’in çözümlenen değeri olamazlar.

Derinlemesine İnceleme

Promise’i Sunucu Bileşeninde mi yoksa İstemci Bileşeninde mi çözümlemeliyim?

Promise, Sunucu Bileşeni’nden İstemci Bileşeni’ne aktarılabilir ve İstemci Bileşeni içerisinde use API kullanarak çözümlenebilir. Yanı sıra istersen Promise’i Sunucu Bileşeni içerisinde await kullanarak çözümleyebilir ve gerekli veriyi İstemci Bileşeni içerisine prop olarak iletebilirsin.

export default async function App() {
const messageContent = await fetchMessage();
return <Message messageContent={messageContent} />
}

Ancak bir Sunucu Bileşeninde await kullanmak, await deyimi bitene kadar bileşenin oluşturulmasını engelleyecektir. Bir Sunucu Bileşeninden bir İstemci Bileşenine bir Promise geçirmek, Promise’in Sunucu Bileşeninin oluşturulmasını engellemesini önler.

Reddedilen Promise’ler ile başa çıkmak

Bazen use’a aktarılan Promise reddedilebilir. Reddedilen Promise’leri şu şekilde yönetebilirsiniz:

  1. Error Boundary ile kullanıcılara hata gösterme
  2. Promise.catch ile alternatif değer sağlama

Tuzak

use, try-catch bloğu içerisinde çağırılamaz. Try-catch bloğu yerine bileşeni Error Boundary içerisine ekleyin, ya da Promise’in .catch methodundan yararlanarak alternatif bir değer sağlayın.

Error Boundary ile kullanıcılara hata gösterme

Bir Promise reddedildiğinde kullanıcıya hata göstermek istiyorsanız, Error Boundary kullanabilirsiniz.
Error Boundary kullanmak için, use API’sini çağırdığınız bileşeni bir Error Boundary ile sarın.
Eğer use fonksiyonuna iletilen Promise reddedilirse, Error Boundary için tanımlanan fallback içerik görüntülenecektir.

"use client";

import { use, Suspense } from "react";
import { ErrorBoundary } from "react-error-boundary";

export function MessageContainer({ messagePromise }) {
  return (
    <ErrorBoundary fallback={<p>⚠️Bir şeyler yanlış gitti</p>}>
      <Suspense fallback={<p>⌛Mesaj indiriliyor...</p>}>
        <Message messagePromise={messagePromise} />
      </Suspense>
    </ErrorBoundary>
  );
}

function Message({ messagePromise }) {
  const content = use(messagePromise);
  return <p>Aktarılan mesaj: {content}</p>;
}

Promise.catch methodunu kullanarak alternatif bir veri sunmak

Eğer use’a aktarılan Promise reddedildiğinde yerine alternatif bir değer sağlamak istiyorsan Promise’in catch methodunu kullanabilirsin.

import { Message } from './message.js';

export default function App() {
const messagePromise = new Promise((resolve, reject) => {
reject();
}).catch(() => {
return "yeni mesaj bulunamadı.";
});

return (
<Suspense fallback={<p>Mesaj bekleniyor...</p>}>
<Message messagePromise={messagePromise} />
</Suspense>
);
}

Promise’in catch methodunu kullanmak için Promise objesinden catch’i çağır. catch tek bir argüman alır: Bir hata mesajını argüman olarak alan bir fonksiyon. catch’e geçirilen fonskiyon tarafından döndürülen her şey, Promise’in çözümlenen değeri olarak kullanılacaktır.


Sorun Giderme

“Suspense İstisnası: Bu gerçek bir hata değil!”

Ya use fonksiyonunu bir React Component veya Hook fonksiyonu dışında çağırıyorsunuz,
ya da use’u bir try–catch bloğu içinde çağırıyorsunuz. Eğer use’u bir try–catch bloğu içinde çağırıyorsanız, bileşeninizi bir Error Boundary ile sarın,
veya Promise’in catch metodunu kullanarak hatayı yakalayın ve Promise’i başka bir değerle çözümleyin (resolve edin). Bu örneklere bakın.

Eğer use’u bir React Bileşeni veya Hook fonksiyonu dışında çağırıyorsanız use çağrısını bir React Bileşeni veya Hook fonksiyonu içerisine taşıyın.

function MessageComponent({messagePromise}) {
function download() {
// ❌ `use`, bir Bileşen veya Hook olmayan fonksiyon tarafından çağırılıyor
const message = use(messagePromise);
// ...

Bunun yerine, use fonksiyonunu herhangi bir bileşen kapanışının dışında çağırın. use fonksiyonunu çağıran fonksiyon bir bileşen veya Hook olmalıdır.

function MessageComponent({messagePromise}) {
// ✅ `use` bir bileşen içerisine çağırılıyor.
const message = use(messagePromise);
// ...