hydrateRoot, daha önce react-dom/server tarafından oluşturulmuş olan HTML içeriğini bir tarayıcı DOM düğümünün içinde React bileşenlerini görüntülemenize olanak tanır.

const root = hydrateRoot(domNode, reactNode, options?)

Referans

hydrateRoot(domNode, reactNode, options?)

hydrateRoot çağrısını, bir sunucu ortamında React tarafından zaten render edilmiş olan mevcut HTML’ye React’i “bağlamak” için kullanın.

import { hydrateRoot } from 'react-dom/client';

const domNode = document.getElementById('root');
const root = hydrateRoot(domNode, reactNode);

React, domNode içinde bulunan HTML’ye bağlanacak ve içindeki DOM’un yönetimini devralacaktır. Tamamen React ile oluşturulmuş bir uygulama genellikle yalnızca bir hydrateRoot çağrısına ve onun kök bileşenine sahip olacaktır.

Daha fazla örnek için aşağıya bakın.

Parametreler

  • domNode: Sunucuda kök eleman olarak render edilmiş bir DOM elemanı.

  • reactNode: Mevcut HTML’i render etmek için kullanılan “React düğümü”. Bu genellikle ReactDOM Server yöntemiyle render edilmiş <App /> gibi bir JSX parçası olacaktır, örneğin renderToPipeableStream(<App />) ile.

  • isteğe bağlı options: Bu React kökü için seçenekler içeren bir nesne.

    • Canary only isteğe bağlı onCaughtError: React bir Error Boundary içinde hata yakaladığında çağrılan geri çağırma fonksiyonu. Error Boundary tarafından yakalanan error ile ve componentStack içeren bir errorInfo nesnesi ile çağrılır.
    • Canary only isteğe bağlı onUncaughtError: Bir hata fırlatıldığında ve Error Boundary tarafından yakalanmadığında çağrılan geri çağırma fonksiyonu. Fırlatılan error ve componentStack içeren bir errorInfo nesnesi ile çağrılır.
    • isteğe bağlı onRecoverableError: React hatalardan otomatik olarak kurtarıldığında çağrılan geri çağırma fonksiyonu. React’in fırlattığı error ve componentStack içeren bir errorInfo nesnesi ile çağrılır. Bazı kurtarılabilir hatalar, orijinal hata nedenini error.cause olarak içerebilir.
    • isteğe bağlı identifierPrefix: React’in useId ile oluşturulan ID’ler için kullandığı bir string öneki. Aynı sayfada birden fazla kök kullanırken çakışmaları önlemek için faydalıdır. Sunucuda kullanılanla aynı önek olmalıdır.

Döndürülenler

hydrateRoot, iki metoda sahip bir nesne döndürür: render ve unmount.

Uyarılar

  • hydrateRoot() render edilen içeriğin sunucu tarafından render edilen içerik ile aynı olmasını bekler. Uyumsuzlukları hata olarak görmeli ve düzeltmelisiniz.
  • Geliştirme modunda, React hidrasyon sırasında uyumsuzluklar hakkında uyarılar verir. Uyumsuzluklar durumunda, özellik farklılıklarının düzeltilmesi garanti edilmez. Bu, performans nedenleriyle önemlidir çünkü çoğu uygulamada uyumsuzluklar nadirdir ve tüm işaretlemeleri doğrulamak oldukça maliyetli olabilir.
  • Uygulamanızda muhtemelen yalnızca bir hydrateRoot çağrısı olacaktır. Eğer bir framework kullanıyorsanız, bu çağrıyı sizin için yapabilir.
  • Uygulamanızda zaten render edilmiş bir HTML yoksa, hydrateRoot() kullanmak desteklenmez. Bunun yerine createRoot() kullanın.

root.render(reactNode)

Bir tarayıcı DOM elemanı için hidrasyona uğramış bir React kökünde bir React bileşenini güncellemek için root.render çağrısı yapın.

root.render(<App />);

React, hidrasyona uğramış root içinde <App />’i güncelleyecektir.

Daha fazla örnek için aşağıya bakın.

Parametreler

  • reactNode: Güncellemek istediğiniz bir “React düğümü”. Bu genellikle <App /> gibi bir JSX parçası olacaktır, ancak aynı zamanda createElement() ile oluşturulmuş bir React elemanı, bir string, bir sayı, null veya undefined de iletebilirsiniz.

Döndürülenler

root.render undefined döndürür.

Uyarılar

  • Eğer kök hidrasyonu tamamlamadan önce root.render çağrısı yaparsanız, React mevcut sunucu tarafından render edilmiş HTML içeriğini temizler ve tüm kökü istemci tarafı render’lamaya geçirir.

root.unmount()

Bir React kökü içindeki render edilmiş bir ağacı yok etmek için root.unmount çağrısı yapın.

root.unmount();

Tamamen React ile oluşturulmuş bir uygulama genellikle root.unmount çağrısı yapmaz.

Bu, özellikle React kök DOM düğümünüzün (veya onun herhangi bir atasının) başka bir kod tarafından DOM’dan kaldırılması durumunda kullanışlıdır. Örneğin, geçersiz sekmeleri DOM’dan kaldıran bir jQuery sekme paneli hayal edin. Bir sekme kaldırıldığında, içindeki her şey (React kökleri dahil) DOM’dan da kaldırılacaktır. React’e, root.unmount çağrısı yaparak kaldırılan kökün içeriğini yönetmeyi “durdurması” gerektiğini belirtmelisiniz. Aksi takdirde, kaldırılan kökün içindeki bileşenler, abonelikler gibi kaynakları temizleyip serbest bırakmazlar.

root.unmount çağrısı, kök bileşenindeki tüm bileşenleri unmount eder ve React’i kök DOM düğümünden “ayırır”, bu da ağaçtaki tüm olay yöneticilerini veya durumu kaldırmayı içerir.

Parametreler

root.unmount herhangi bir parametre kabul etmez.

Döndürülenler

root.unmount undefined döndürür.

Uyarılar

  • root.unmount çağrısı, ağaçtaki tüm bileşenleri unmount eder ve React’i kök DOM düğümünden “ayırır”.

  • Bir kez root.unmount çağrıldıktan sonra, kök üzerinde tekrar root.render çağrısı yapamazsınız. Unmount edilmiş bir kök üzerinde root.render çağırmaya çalışmak, “Unmount edilmiş bir kök güncellenemez” hatasını fırlatır.


Kullanım

Sunucu tarafından render edilen HTML’i hidrasyona uğratma

Eğer uygulamanızın HTML’i react-dom/server ile oluşturulduysa, bunu istemcide hidrasyona uğratmanız gerekir.

import { hydrateRoot } from 'react-dom/client';

hydrateRoot(document.getElementById('root'), <App />);

Bu, tarayıcı DOM düğümü içindeki sunucu HTML’ini, uygulamanız için React bileşeni ile hidrasyona uğratacaktır. Genellikle, bunu başlangıçta bir kez yaparsınız. Eğer bir framework kullanıyorsanız, bu işlemi arka planda sizin için yapabilir.

Uygulamanızı hidrasyona uğratmak için, React bileşenlerinizin mantığını sunucudan gelen ilk oluşturulmuş HTML’e “bağlar”. Hidrasyon, sunucudan gelen ilk HTML anlık görüntüsünü, tarayıcıda çalışan tamamen etkileşimli bir uygulamaya dönüştürür.

import './styles.css';
import { hydrateRoot } from 'react-dom/client';
import App from './App.js';

hydrateRoot(
  document.getElementById('root'),
  <App />
);

hydrateRoot fonksiyonunu tekrar çağırmanıza veya başka yerlerde çağırmanıza gerek yoktur. Bundan sonra, React uygulamanızın DOM’unu yönetecektir. Kullanıcı arayüzünü güncellemek için, bileşenleriniz bunun yerine use state kullanacaktır.

Tuzak

hydrateRoot fonksiyonuna geçirdiğiniz React ağacının, sunucuda ürettiği aynı çıktıyı üretmesi gerekir.

Bu, kullanıcı deneyimi için önemlidir. Kullanıcı, JavaScript kodunuz yüklenmeden önce bir süre sunucu tarafından üretilen HTML’e bakarak bekleyecektir. Sunucu render’ı, çıktısının HTML anlık görüntüsünü göstererek uygulamanın daha hızlı yüklendiği yanılsamasını yaratır. Farklı içeriklerin aniden gösterilmesi, bu yanılsamayı bozar. Bu nedenle, sunucu render çıktısının, istemcideki ilk render çıktısı ile eşleşmesi gerekir.

Hidrasyon hatalarına yol açan en yaygın nedenler şunlardır:

  • Kök düğüm içindeki React tarafından üretilen HTML etrafındaki ekstra boşluklar (yeni satırlar gibi).
  • Render mantığınızda typeof window !== 'undefined' gibi kontroller kullanmak.
  • Render mantığınızda yalnızca tarayıcıya özgü API’ler, örneğin window.matchMedia kullanmak.
  • Sunucuda ve istemcide farklı veriler render etmek.

React bazı hidrasyon hatalarından kurtulabilir, ancak bunları diğer hatalar gibi düzeltmelisiniz. En iyi durumda, performans düşüşüne yol açarlar; en kötü durumda ise olay yöneticileri yanlış elemanlara eklenebilir.


Tüm bir belgeyi hidrasyon yapmak

Tamamen React ile oluşturulmuş uygulamalar, tüm belgeyi JSX olarak render edebilir, buna <html> etiketi de dahildir:

function App() {
return (
<html>
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="/styles.css"></link>
<title>My app</title>
</head>
<body>
<Router />
</body>
</html>
);
}

Tüm belgeyi hidrasyon yapmak için, document globalini hydrateRoot fonksiyonuna ilk argüman olarak geçirin:

import { hydrateRoot } from 'react-dom/client';
import App from './App.js';

hydrateRoot(document, <App />);

Kaçınılmaz hidrasyon uyumsuzluğu hatalarını bastırma

Eğer tek bir elemanın özelliği veya metin içeriği sunucu ve istemci arasında kaçınılmaz şekilde farklıysa (örneğin bir zaman damgası), hidrasyon uyumsuzluğu uyarısını sessize alabilirsiniz.

Bir elemandaki hidrasyon uyarılarını sessize almak için suppressHydrationWarning={true} ekleyin:

export default function App() {
  return (
    <h1 suppressHydrationWarning={true}>
      Güncel Tarih: {new Date().toLocaleDateString()}
    </h1>
  );
}

Bu yalnızca bir seviye derinliğe kadar çalışır ve bir kaçış mekanizması olarak tasarlanmıştır. Aşırı kullanmayın. Eğer metin içeriği değilse, React yine de bunu düzeltmeye çalışmaz, bu nedenle gelecekteki güncellemelerle tutarsız kalabilir.


Farklı istemci ve sunucu içeriklerini yönetme

Eğer kasıtlı olarak sunucuda ve istemcide farklı bir şey render etmeniz gerekiyorsa, iki geçişli bir render yapabilirsiniz. İstemcide farklı bir şey render eden bileşenler, isClient gibi bir state variable okuyabilir, bu değişkeni bir Effect içinde true olarak ayarlayabilirsiniz:

import { useState, useEffect } from "react";

export default function App() {
  const [isClient, setIsClient] = useState(false);

  useEffect(() => {
    setIsClient(true);
  }, []);

  return (
    <h1>
      {isClient ? 'Is Client' : 'Is Server'}
    </h1>
  );
}

Bu şekilde, ilk render geçişi sunucuyla aynı içeriği render eder, uyumsuzlukları önler, ancak hidrasyon hemen sonrasında senkronize bir şekilde ek bir geçiş yapılır.

Tuzak

Bu yaklaşım, bileşenlerinizin iki kez render edilmesi gerektiği için hidrasyonu yavaşlatır. Yavaş bağlantılarda kullanıcı deneyimine dikkat edin. JavaScript kodu, başlangıçtaki HTML render işleminden önemli ölçüde daha geç yüklenebilir, bu nedenle hidrasyondan hemen sonra farklı bir kullanıcı arayüzü render edilmesi, kullanıcıya garip gelebilir.


Hidrasyon yapılmış bir kök bileşenini güncelleme

Kök hidrasyon işlemini tamamladıktan sonra, kök React bileşenini güncellemek için root.render çağrısı yapabilirsiniz. createRoot ile farklı olarak, genellikle bunu yapmanız gerekmez çünkü başlangıçtaki içerik zaten HTML olarak render edilmiştir.

Eğer hidrasyondan sonra bir noktada root.render çağrısı yapar ve bileşen ağacı yapısı daha önce render edilmiş olan ile eşleşirse, React durumu koruyacaktır. Bu örnekte, her saniye yapılan tekrar eden render çağrılarının yıkıcı olmadığını gösteren şekilde, girdi kutusuna yazmaya devam edebileceğinizi fark edeceksiniz:

import { hydrateRoot } from 'react-dom/client';
import './styles.css';
import App from './App.js';

const root = hydrateRoot(
  document.getElementById('root'),
  <App counter={0} />
);

let i = 0;
setInterval(() => {
  root.render(<App counter={i} />);
  i++;
}, 1000);

Hidrasyon yapılmış bir kökte root.render çağrısı yapmak yaygın değildir. Bunun yerine, genellikle bileşenlerden birinde update state.

Yakalanmamış hatalar için bir diyalog göster

Test Ortamı (Canary)

onUncaughtError yalnızca en son React Canary sürümünde kullanılabilir.

Varsayılan olarak, React tüm yakalanmamış hataları konsola kaydeder. Kendi hata raporlama sisteminizi uygulamak için isteğe bağlı onUncaughtError kök seçeneğini sağlayabilirsiniz:

import { hydrateRoot } from 'react-dom/client';

const root = hydrateRoot(
document.getElementById('root'),
<App />,
{
onUncaughtError: (error, errorInfo) => {
console.error(
'Yakalanmamış hata',
error,
errorInfo.componentStack
);
}
}
);
root.render(<App />);

onUncaughtError seçeneği, iki argüman ile çağrılan bir fonksiyondur:

  1. Fırlatılan error.
  2. Hatanın componentStack’ini içeren bir errorInfo nesnesi.

onUncaughtError kök seçeneğini, hata diyalogları göstermek için kullanabilirsiniz:

import { hydrateRoot } from "react-dom/client";
import App from "./App.js";
import {reportUncaughtError} from "./reportError";
import "./styles.css";
import {renderToString} from 'react-dom/server';

const container = document.getElementById("root");
const root = hydrateRoot(container, <App />, {
  onUncaughtError: (error, errorInfo) => {
    if (error.message !== 'Known error') {
      reportUncaughtError({
        error,
        componentStack: errorInfo.componentStack
      });
    }
  }
});

Error Boundary hatalarını görüntüleme

Test Ortamı (Canary)

onCaughtError yalnızca en son React Canary sürümünde kullanılabilir.

Varsayılan olarak, React bir Error Boundary tarafından yakalanan tüm hataları console.error içine kaydeder. Bu davranışı değiştirmek için, bir Error Boundary tarafından yakalanan hatalar için isteğe bağlı onCaughtError kök seçeneğini sağlayabilirsiniz:

import { hydrateRoot } from 'react-dom/client';

const root = hydrateRoot(
document.getElementById('root'),
<App />,
{
onCaughtError: (error, errorInfo) => {
console.error(
'Yakalanan hata',
error,
errorInfo.componentStack
);
}
}
);
root.render(<App />);

onCaughtError seçeneği, iki argüman ile çağrılan bir fonksiyondur:

  1. Boundary tarafından yakalanan error.
  2. Hatanın componentStack’ini içeren bir errorInfo nesnesi.

onCaughtError kök seçeneğini, hata diyalogları göstermek veya bilinen hataların loglanmasını engellemek için kullanabilirsiniz:

import { hydrateRoot } from "react-dom/client";
import App from "./App.js";
import {reportCaughtError} from "./reportError";
import "./styles.css";

const container = document.getElementById("root");
const root = hydrateRoot(container, <App />, {
  onCaughtError: (error, errorInfo) => {
    if (error.message !== 'Known error') {
      reportCaughtError({
        error,
        componentStack: errorInfo.componentStack
      });
    }
  }
});

Kurtarılabilir hidrasyon uyumsuzluğu hataları için bir diyalog göster

React, bir hidrasyon uyumsuzluğu ile karşılaştığında, otomatik olarak istemci tarafında render ederek durumu kurtarmaya çalışır. Varsayılan olarak, React hidrasyon uyumsuzluğu hatalarını console.error içine kaydeder. Bu davranışı değiştirmek için, isteğe bağlı onRecoverableError kök seçeneğini sağlayabilirsiniz:

import { hydrateRoot } from 'react-dom/client';

const root = hydrateRoot(
document.getElementById('root'),
<App />,
{
onRecoverableError: (error, errorInfo) => {
console.error(
'Yakalanan hata',
error,
error.cause,
errorInfo.componentStack
);
}
}
);

onRecoverableError seçeneği, iki argüman ile çağrılan bir fonksiyondur:

  1. React’in attığı error. Bazı hatalar, orijinal nedeni error.cause olarak içerebilir.
  2. Hatanın componentStack’ini içeren bir errorInfo nesnesi.

onRecoverableError kök seçeneğini, hidrasyon uyumsuzlukları için hata diyalogları göstermek amacıyla kullanabilirsiniz:

import { hydrateRoot } from "react-dom/client";
import App from "./App.js";
import {reportRecoverableError} from "./reportError";
import "./styles.css";

const container = document.getElementById("root");
const root = hydrateRoot(container, <App />, {
  onRecoverableError: (error, errorInfo) => {
    reportRecoverableError({
      error,
      cause: error.cause,
      componentStack: errorInfo.componentStack
    });
  }
});

Sorun giderme

Bir hata alıyorum: “root.render fonksiyonuna ikinci bir argüman ilettiniz”

Yaygın bir hata, hydrateRoot için olan seçenekleri root.render(...) fonksiyonuna iletmektir:

Console
Uyarı: root.render(…) fonksiyonuna ikinci bir argüman ilettiniz, ancak bu fonksiyon yalnızca bir argüman kabul eder.

Düzeltmek için, kök seçeneklerini root.render(...) yerine hydrateRoot(...) fonksiyonuna iletin:

// 🚩 Yanlış: root.render yalnızca bir argüman alır.
root.render(App, {onUncaughtError});

// ✅ Doğru: createRoot'a seçenekleri iletin.
const root = hydrateRoot(container, <App />, {onUncaughtError});