createRoot memungkinkan Anda untuk membuat sebuah akar untuk menampikan komponen React dalam node DOM pada peramban.

const root = createRoot(domNode, options?)

Referensi

createRoot(domNode, options?)

Panggil createRoot untuk membuat akar React untuk menampilkan konten di elemen DOM pada peramban.

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

const domNode = document.getElementById('root');
const root = createRoot(domNode);

React akan membuat sebuah akar untuk domNode dan mengambil alih pengelolaan DOMnya. Setelah Anda membuat akar, Anda harus memanggil root.render untuk menampilkan komponen React di dalam DOM tersebut:

root.render(<App />);

Aplikasi yang sepenuhnya dibuat dengan React biasanya cukup memanggil createRoot sekali saja untuk komponen akarnya. Sedangkan untuk halaman yang “dihiasi” oleh bagian yang menggunakan React mungkin dapat memiliki akar sebanyak yang diperlukan.

Lihat contoh-contoh lainnya di bawah ini.

Parameter

  • domNode: Sebuah elemen DOM. React akan membuat akar untuk elemen DOM ini dan memungkinkan Anda untuk memanggil fungsi lain pada akar, seperti render untuk menampilkan konten React yang sudah di-render.

  • opsional options: Sebuah objek dengan opsi-opsi berikut untuk akar React ini.

    • Canary only opsional onCaughtError: Callback called when React catches an error in an Error Boundary. Called with the error caught by the Error Boundary, and an errorInfo object containing the componentStack.
    • Canary only opsional onUncaughtError: Callback called when an error is thrown and not caught by an Error Boundary. Called with the error that was thrown, and an errorInfo object containing the componentStack.
    • opsional onRecoverableError: Callback yang dipanggil saat React berhasil pulih secara otomatis dari kesalahan. Dipanggil dengan error yang dikembalikan React, dan obyek errorInfo berisi componentStack. Beberapa kesalahan yang dapat dipulihkan mungkin akan berisi kesalahan aslinya sebagai error.cause.
    • opsional identifierPrefix: Awalan string yang digunakan React untuk ID yang dihasilkan oleh useId. Berguna untuk mencegah konflik saat menggunakan banyak akar pada halaman yang sama.

Kembalian

createRoot mengembalikan sebuah objek dengan dua method: render dan unmount.

Catatan Penting

  • Jika aplikasi Anda di-render oleh server, penggunaan createRoot() tidak didukung. Sebagai gantinya, gunakan hydrateRoot().
  • Anda mungkin hanya akan memiliki satu panggilan createRoot pada aplikasi Anda. Jika Anda menggunakan framework, biasanya pemanggilan fungsi ini sudah dilakukan oleh framework tersebut.
  • Saat Anda ingin me-render sebagian JSX pada bagian lain dari pohon DOM yang bukan turunan dari komponen Anda (contohnya modal atau tooltip), gunakan createPortal, bukan createRoot.

root.render(reactNode)

Panggil root.render untuk menampilkan sebuah JSX (“React node”) dalam node DOM milik akar React pada peramban.

root.render(<App />);

React akan menampilkan <App /> dalam root, dan mengambil alih pengelolaan DOM di dalamnya.

Lihat contoh-contoh lainnya di bawah ini.

Parameter

  • reactNode: Sebuah React Node yang Anda ingin tampilkan. Biasanya berupa sebuah JSX seperti <App />, namun Ada juga dapat memberikan sebuah elemen React yang dibuat dengan createElement(), sebuah string, sebuah angka (number), null atau undefined.

Kembalian

root.render mengembalikan undefined.

Catatan Penting

  • Pada pemanggilan root.render pertama kali, React akan menghapus seluruh konten HTML yang ada pada akar React, sebelum me-render komponen React di dalamnya.

  • Jika node DOM akar Anda memiliki HTML yang dibuat oleh React pada server, atau proses build, gunakan hydrateRoot() agar event handler dapat dikaitkan dengan HTML yang ada.

  • Jika Anda memanggil render pada akar yang sama berulang kali, React akan memperbarui DOM sebisa mungkin hingga menyamai JSX terakhir yang Anda berikan. React akan memutuskan bagian mana dari DOM yang dapat digunakan kembali dan bagian mana yang perlu dibuat ulang, dengan melakukan “pencocokan” dengan pohon yang telah di-render sebelumnya. Pemanggilan kembali render di akar yang sama mirip dengan memanggil fungsi set pada komponen akar: React menghindari pembaharuan DOM yang tidak diperlukan.


root.unmount()

Panggil root.unmount untuk memusnakan pohon yang telah di-render dalam akar React.

root.unmount();

Sebuah aplikasi yang dibuat sepenuhnya dengan React biasanya tidak perlu memanggil root.unmount.

Fungsi ini biasanya berguna saat node DOM pada akar React (atau turunan lainnya) mungkin dapat terhapus dari DOM oleh kode lain. Sebagai contoh, bayangkan sebuah panel tab jQuery yang menghapus tab nonaktif dari DOM. Jika tab tersebut terhapus, seluruh isi dari DOM tersebut (termasuk akar React) juga akan ikut terhapus. Pada kasus ini, Anda perlu memberitahukan React untuk “stop” mengelola konten DOM akar yang terhapus dengan memanggil root.unmount. Jika tidak, komponen yang ada di dalam akar tersebut tidak tahu kalau mereka harus membersihkan dan membebaskan resources global seperti subscriptions.

Memanggil root.unmount akan meng-unmount seluruh komponen di dalam akar, dan “melepaskan” React dari dalam node DOM akar, termasuk menghapus event handlers dan state yang ada pada pohon.

Parameter

root.unmount tidak menerima parameter apapun.

Kembalian

root.unmount mengembalikan undefined.

Catatan penting

  • Pemanggilan root.unmount akan meng-unmount seluruh komponen pada pohon dan “melepaskan” React dari node DOM akar.

  • Begitu Anda memanggil root.unmount, Anda tidak dapat memanggil root.render kembali pada akar yang sama. Percobaan memanggil root.render pada akar yang sudah di-unmount akan menyebabkan kesalahan “Cannot update an unmounted root”. Walaupun begitu, Anda dapat membuat akar yang baru untuk node DOM yang sama setelah node pada akar sebelumnya telah di-unmount.


Penggunaan

Me-render aplikasi yang dibuat sepenuhnya dengan React

Jika aplikasi Anda dibuat sepenuhnya dengan React, buatlah sebuah akar untuk seluruh bagian aplikasi Anda.

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

const root = createRoot(document.getElementById('root'));
root.render(<App />);

Biasanya, Anda cukup menjalankan kode ini sekali saja pada startup. Kode ini akan:

  1. Mencari node DOM pada peramban, yang didefinisikan di HTML Anda.
  2. Menampilkan komponen React untuk aplikasi Anda didalamnya.
import { createRoot } from 'react-dom/client';
import App from './App.js';
import './styles.css';

const root = createRoot(document.getElementById('root'));
root.render(<App />);

Jika aplikasi Anda dibuat sepenuhnya dengan React, Anda seharusnya tidak perlu membuat akar-akar lainnya, atau memanggil root.render kembali.

Kedepannya, React akan mengelola DOM tersebut untuk seluruh aplikasi Anda. Untuk menambahkan komponen-komponen lain, pasangkan mereka di dalam komponen App. Saat Anda perlu memperbarui UI tersebut, Anda dapat melakukannya dengan menggunakan state. Saat Anda ingin menampilkan konten ekstra seperti modal atau tooltip diluar dari node DOM, render komponen tersebut dengan sebuah portal.

Catatan

Saat HTML Anda kosong, pengguna akan melihat sebuah halaman kosong sampai kode JavaScript aplikasi selesai dimuat dan berjalan.

<div id="root"></div>

Ini dapat terasa sangat lambat! Untuk mengatasi masalah ini, Anda dapat membuat HTML awal dari komponen Anda pada server atau saat proses build Sehingga pengunjung dapat membaca teks, melihat gambar dan mengklik tautan sebelum kode JavaScript apapun selesai dimuat. Kami merekomendasikan untuk menggunakan sebuah framework yang telah melakukan optimisasi ini sejak awal. Bergantung dari kapan proses ini berjalan, ini dapat dipanggil sebagai server-side rendering (SSR) atau static site generation (SSG).

Sandungan

Aplikasi yang di-render pada server atau pembuatan statis harus memanggil hydrateRoot, bukan createRoot. React kemudian akan meng-hydrate (menggunakan ulang) node-node DOM dari HTML Anda, alih-alih menghancurkan dan membuat ulang node tersebut.


Me-render halaman yang sebagian dibuat dengan React

Jika halaman Anda tidak dibuat sepenuhnya dengan React, Anda dapat memanggil createRoot lebih dari sekali untuk membuat akar dari setiap bagian level teratas yang dikelola React. Anda dapat menampilkan konten yang berbeda untuk setip akar dengan memanggil root.render.

Di sini, dua komponen React yang berbeda di-render kedalam dua node DOM yang didefinisikan dalam file index.html.

import './styles.css';
import { createRoot } from 'react-dom/client';
import { Comments, Navigation } from './Components.js';

const navDomNode = document.getElementById('navigation');
const navRoot = createRoot(navDomNode); 
navRoot.render(<Navigation />);

const commentDomNode = document.getElementById('comments');
const commentRoot = createRoot(commentDomNode); 
commentRoot.render(<Comments />);

Anda dapat juga membuat node DOM baru dengan document.createElement() dan menambahkannya ke dalam dokumen secara langsung.

const domNode = document.createElement('div');
const root = createRoot(domNode);
root.render(<Comment />);
document.body.appendChild(domNode); // Anda dapat menambahkan kode ini di manapun dalam dokumen

Untuk memusnahkan pohon React dari node DOM dan membersihkan seluruh resources yang digunakan, panggil root.unmount.

root.unmount();

Hal ini biasanya berguna saat komponen React Anda berada dalam aplikasi yang menggunakan framework yang berbeda.


Memperbarui komponen akar

Anda dapat memanggil render lebih dari sekali untuk akar yang sama. Selama pohon komponen tersebut sama dengan yang sebelumnya telah di-render, React akan menjaga statenya. Perhatikan bagaimana Anda dapat mengetik pada input, yang berarti pembaruan dari pemanggilan render yang berulang setiap detik pada contoh ini tidak desktruktif.

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

const root = createRoot(document.getElementById('root'));

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

Pemanggilan render berulang kali biasanya tidak wajar. Pada umumnya komponen Anda akan memperbarui state.

Menampilkan dialog untuk error yang tidak ditangkap

Canary

onCaughtError hanya tersedia di rilis Canary React terbaru.

Secara bawaan, React akan me-log semua error yang tidak ditangkap ke konsol. Untuk mengimplementasikan pelaporan error Anda sendiri, Anda dapat menyediakan opsi root onUncaughtError opsional:

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

const root = createRoot(
document.getElementById('root'),
{
onUncaughtError: (error, errorInfo) => {
console.error(
'Uncaught error',
error,
errorInfo.componentStack
);
}
}
);
root.render(<App />);

Pengaturan onUncaughtError adalah fungsi yang dipanggil dengan dua argumen:

  1. The error yang dilempar.
  2. Obyek errorInfo yang berisi componentStack dari error tersebut.

Anda dapat menggunakan opsi root onUncaughtError untuk menampilkan dialog error:

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

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

Menampilkan kesalahan dari Error Boundary

Canary

onCaughtError hanya tersedia di rilis Canary React terbaru.

Secara bawaan, React akan me-log semua error yang ditangkap di Error Boundary ke console.error. Untuk mengesampingkan perilaku ini, Anda dapat memberikan opsi root onCaughtError opsional untuk kesalahan yang ditangkap oleh Error Boundary:

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

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

Pengaturan onUncaughtError adalah fungsi yang dipanggil dengan dua argumen:

  1. error yang ditangkap oleh boundary.
  2. Obyek errorInfo yang berisi componentStack dari error tersebut.

Anda dapat menggunakan opsi root onUncaughtError untuk menunjukkan dialog error atau memfilter error yang diketahui dari logging:

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

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

Menampilkan dialog untuk error yang dapat dipulihkan

React dapat secara otomatis me-render komponen untuk kedua kalinya guna mencoba memulihkan dari error yang terjadi saat me-render. Jika berhasil, React akan me-log error yang dapat dipulihkan ke konsol untuk memberi tahu pengembang aplikasi. Untuk mengatasi perilaku ini, Anda dapat memberikan opsi root onRecoverableError opsional:

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

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

Pengaturan onRecoverableError adalah fungsi yang dipanggil dengan dua argumen:

  1. error yang dilempar React. Beberapa error mungkin mengandung penyebab awal sebagai error.cause.
  2. Obyek errorInfo yang mengandung componentStack dari error tersebut.

Anda dapat menggunakan opsi root onRecoverableError untuk menampilkan dialog error:

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

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


Pemecahan masalah

Saya telah membuat sebuah akar, namun tidak ada yang tampil

Pastikan Anda tidak lupa untuk me-render aplikasi Anda dalam akarnya:

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

const root = createRoot(document.getElementById('root'));
root.render(<App />);

Tidak akan ada yang tampil sampai hal tersebut Anda lakukan.


Saya mendapatkan pesan kesalahan: “You passed a second argument to root.render

Kesalahan umum adalah mengoper opsi untuk createRoot ke root.render(...):

Konsol
Warning: You passed a second argument to root.render(…) but it only accepts one argument.

Untuk memperbaikinya, oper opsi akar ke createRoot(...), bukan root.render(...):

// 🚩 Wrong: root.render only takes one argument.
root.render(App, {onUncaughtError});

// ✅ Correct: pass options to createRoot.
const root = createRoot(container, {onUncaughtError});
root.render(<App />);

Saya mendapatkan pesan kesalahan: “Target container is not a DOM element

Pesan kesalahan ini menyatakan apapun yang Anda berikan ke createRoot bukan sebuah simpul DOM.

Jika Anda tidak yakin apa yang terjadi, cobalah me-log variabel tersebut:

const domNode = document.getElementById('root');
console.log(domNode); // ???
const root = createRoot(domNode);
root.render(<App />);

Sebagai contoh, jika domNode tersebut null, artinya getElementById mengembalikan null. Hal ini terjadi jika tidak ada node dalam dokumen yang memiliki ID yang Anda coba cari. Ada beberapa alasan yang memungkinkan:

  1. ID yang Anda cari mungkin berbeda dengan ID yang Anda gunakan pada file HTML Anda. Cek typo!
  2. Tag <script> pada bundle Anda tidak dapat “melihat” node DOM apapun yang muncul setelahnya dalam HTML.

Kesalahan umum lainnya untuk pesan kesalahan ini adalah penulisan createRoot(<App />) yang seharusnya createRoot(domNode).


Saya mendapatkan pesan kesalahan: “Functions are not valid as a React child.

Pesan kesalahan ini menyatakan bahwa apapun yang Anda berikan pada root.render bukan sebuah komponen React.

Hal ini mungkin terjadi jika Anda memanggil root.render dengan Component, yang seharusnya <Component />.

// 🚩 Salah: App adalah fungsi, bukan komponen.
root.render(App);

// ✅ Benar: <App /> adalah komponen.
root.render(<App />);

Kemungkinan lainnya, saat Anda memberikan sebuah fungsi ke root.render, yang seharusnya hasil dari pemanggilannya.

// 🚩 Salah: createApp adalah fungsi, bukan komponen.
root.render(createApp);

// ✅ Benar: panggil createApp untuk mengembalikan sebuah komponen.
root.render(createApp());

HTML yang di-render oleh server selalu dibuat ulang dari awal

Jika aplikasi Anda adalah aplikasi yang di-render oleh server dan menggunakan HTML awal yang dibuat oleh React, Anda mungkin akan menyadari bahwa dengan membuat akar dan memanggil root.render menghapus seluruh HTML tersebut dan membuat ulang node-node DOM dari awal. Hal ini dapat memperlambat, mereset fokus dan posisi scroll, dan mungkin menghilangkan input dari pengguna.

Aplikasi yang di-render oleh server harus menggunakan hydrateRoot, bukan createRoot:

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

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

Mohon dicatat bahwa APInya berbeda. Lebih spesifiknya, biasanya tidak akan ada lagi panggilan root.render.