ctx.render()

Merender elemen React, string HTML, atau node DOM ke container tertentu. Saat tidak meneruskan container, secara default merender ke ctx.element, dan otomatis mewarisi ConfigProvider, tema, dll. dari aplikasi.

Skenario Penggunaan

SkenarioDeskripsi
JSBlockMerender konten kustom block (chart, list, card, dll.)
JSField / JSItem / JSColumnMerender tampilan kustom field yang dapat diedit atau kolom tabel
Block DetailBentuk tampilan kustom field di halaman detail

Perhatian: ctx.render() membutuhkan container render. Jika tidak meneruskan container dan ctx.element tidak ada (seperti skenario logika murni tanpa UI), akan melempar error.

Definisi Tipe

render(
  vnode: React.ReactElement | Node | DocumentFragment | string,
  container?: Element | DocumentFragment
): ReactDOMClient.Root | null;
ParameterTipeDeskripsi
vnodeReact.ReactElement | Node | DocumentFragment | stringKonten yang akan dirender
containerElement | DocumentFragment (opsional)Container target render, default ctx.element

Return Value:

  • Saat merender elemen React: mengembalikan ReactDOMClient.Root, untuk memudahkan memanggil root.render() untuk update
  • Saat merender string HTML atau node DOM: mengembalikan null

Penjelasan Tipe vnode

TipePerilaku
React.ReactElement (JSX)Menggunakan createRoot React untuk render, dengan kemampuan React lengkap, otomatis mewarisi konteks aplikasi
stringSetelah dibersihkan oleh DOMPurify menyetel innerHTML container, akan unmount React root yang ada terlebih dahulu
Node (Element, Text, dll.)Mengosongkan container kemudian appendChild, akan unmount React root yang ada terlebih dahulu
DocumentFragmentSub-node fragment ditambahkan ke container, akan unmount React root yang ada terlebih dahulu

Contoh

Render Elemen React (JSX)

const { Button, Card } = ctx.libs.antd;

ctx.render(
  <Card title={ctx.t('Judul')}>
    <Button type="primary" onClick={() => ctx.message.success(ctx.t('Diklik'))}>
      {ctx.t('Tombol')}
    </Button>
  </Card>
);

Render String HTML

ctx.render('<h1>Hello World</h1>');

// Dikombinasikan dengan ctx.t untuk internasionalisasi
ctx.render('<div style="padding:16px">' + ctx.t('Konten') + '</div>');

// Render bersyarat
ctx.render(hasData ? `<ul>${items.map(i => `<li>${i}</li>`).join('')}</ul>` : '<span style="color:#999">' + ctx.t('No data') + '</span>');

Render Node DOM

const div = document.createElement('div');
div.textContent = 'Hello World';
ctx.render(div);

// Render container kosong terlebih dahulu, kemudian serahkan ke library pihak ketiga (seperti ECharts) untuk inisialisasi
const container = document.createElement('div');
container.style.width = '100%';
container.style.height = '400px';
ctx.render(container);
const chart = echarts.init(container);
chart.setOption({ ... });

Menentukan Container Kustom

// Render ke elemen DOM tertentu
const customEl = document.getElementById('my-container');
ctx.render(<div>Konten</div>, customEl);

Pemanggilan Beberapa Kali Akan Mengganti Konten

// Pemanggilan kedua akan mengganti konten yang sudah ada di container
ctx.render(<div>Pertama</div>);
ctx.render(<div>Kedua</div>);  // Hanya menampilkan "Kedua"

Hal yang Perlu Diperhatikan

  • Pemanggilan beberapa kali akan mengganti: setiap ctx.render() akan mengganti konten yang sudah ada di container, tidak akan menambahkan.
  • Keamanan string HTML: HTML yang diteruskan akan dibersihkan oleh DOMPurify, mengurangi risiko XSS, tetapi tetap disarankan untuk menghindari menggabungkan input pengguna yang tidak terpercaya.
  • Jangan langsung mengoperasikan ctx.element: ctx.element.innerHTML sudah deprecated, harus menggunakan ctx.render() secara seragam.
  • Saat tidak ada container perlu meneruskan container: pada skenario di mana ctx.element adalah undefined (seperti dalam modul yang dimuat oleh ctx.importAsync), perlu meneruskan container secara eksplisit.

Terkait

  • ctx.element - Container render default, ctx.render() digunakan saat tidak meneruskan container
  • ctx.libs - Library bawaan seperti React, antd, untuk render JSX
  • ctx.importAsync() - Memuat React/library komponen eksternal sesuai kebutuhan kemudian digunakan dengan ctx.render()