Contoh Vanilla JSX
Bagaimana jika JSX mengembalikan elemen DOM?
- Fungsi
ClickMe membuat tombol dan menampilkan jumlah klik
- Teks diperbarui setiap kali tombol diklik
export default function ClickMe() {
let i = 0;
const el = Click me as HTMLButtonElement;
el.onclick = (e) => {
el.textContent = `Clicked ${++i} times`;
};
return el;
}
Dapat digunakan kembali
- Komponen
ClickMe dapat digunakan beberapa kali dengan masing-masing mempertahankan state yang berbeda
import ClickMe from "./sample1.js";
export default () =>
;
Membuat tree DOM interaktif
- Dengan menggunakan kelas
TodoInput dan TodoList, daftar tugas dapat dikelola
- Item dapat ditambahkan dan dihapus dengan mengkliknya
function TodoInput(attrs: { add: (v: string) => void }) {
const input = as HTMLInputElement;
input.placeholder = 'Add todo item...';
input.onkeydown = (e) => {
if (e.key === 'Enter') {
attrs.add(input.value);
input.value = '';
}
};
return input;
}
class TodoList {
ul = as HTMLUListElement;
add(v: string) {
const item =
- {v}
as HTMLLIElement;
item.onclick = () => item.remove();
this.ul.append(item);
}
}
export default () => {
const list = new TodoList();
list.add('foo');
list.add('bar');
return
list.add(v)} />
{list.ul}
;
};
Pemrosesan data skala besar
- Fungsi
FindNames memproses dan memfilter data dalam jumlah besar lalu menampilkan hasilnya
- Item yang cocok diperbarui secara real-time sesuai nilai input
import { data } from "../fetch-dataset.js";
export default function FindNames() {
const status = as HTMLParagraphElement;
const results = as HTMLUListElement;
const input = as HTMLInputElement;
updateMatches();
function updateMatches() {
const matched = (data.entries().filter(([k]) => k.match(input.value)).toArray());
const matches = (Iterator.from(matched).map(match => ).take(30));
results.replaceChildren(...matches);
status.textContent = `${matched.length} / ${data.size}`;
}
return
{input}
{status}
{results}
;
}
function Item(attrs: { match: [string, number], regex: string }) {
const [name, count] = attrs.match;
const total = ({count});
return
-
{total}
;
}
function highlight(str: string, regex: string) {
if (!regex) return str;
const r = new RegExp(`(${regex})`, 'gi');
return str.replace(r, '$1');
}
Pengenalan imlib
imlib adalah library yang dikembangkan untuk immaculatalibrary.com
- Digunakan untuk membangun minigamemaker.com dan situs web yang sedang Anda baca sekarang
- Library ini dikembangkan karena state yang ada sebelumnya tidak memadai, dan merupakan cara yang paling disukai untuk membuat aplikasi
Ringkasan GN⁺
- Artikel ini menjelaskan cara membuat dan berinteraksi langsung dengan elemen DOM menggunakan JSX
- Artikel ini menunjukkan cara memproses data dalam jumlah besar secara efisien tanpa menggunakan virtual DOM tradisional
- Library
imlib memungkinkan pengembangan aplikasi dengan cara yang sederhana dan intuitif
- Proyek lain dengan fungsi serupa antara lain React dan Vue.js
1 komentar
Komentar Hacker News
Jika yang dikembalikan adalah node DOM sungguhan, maka keunggulan besar pustaka non-JSX seperti JSX dan Lit—yakni API bergaya immediate mode dan model
UI=f(state)—hampir lumpuhAgar bisa mengevaluasi ulang templat dengan state baru dan memperbarui DOM hasil render templat itu secara efisien, yang perlu dikembalikan bukan DOM asli, melainkan deskripsi dari DOM tersebut
Contohnya memperbarui dengan API DOM imperatif seperti
input.onkeydown = ...atauthis.ul.append(item), tetapi mungkin justru menghindari kode seperti ini dan melakukan iterasi item di dalam templat adalah keuntungan utama dari virtual DOMNamun, masalah virtual DOM adalah perhitungan diff yang lambat, dan ini bisa diatasi dengan templat yang memisahkan bagian statis dan dinamis seperti Lit
Malah ini membuat orang berpikir, “UI besar bisa dirender ulang sesuka hati, nanti virtual DOM yang mengurus,” sehingga efeknya justru buruk; performa nyata jelek, tetapi struktur aplikasi sudah telanjur mengeras sehingga sulit diperbaiki tanpa penulisan ulang
Saya melihat alur yang sama di tim saya, dan sebagai arsitek saya mendorong struktur vanilla yang sadar performa berdasarkan masalah yang akan ditemui di React, tetapi ditanggapi dengan sikap “ada banyak cara untuk menghindarinya”
Pada akhirnya, dalam banyak kasus orang memang harus susah sendiri untuk belajar
createElement, dan keuntungan yang dijelaskan tadi datang dari framework dan runtimeSingkatnya, JSX adalah sintaks alternatif untuk pemanggilan fungsi yang punya kegunaan tertentu
Di perusahaan lama, kami memakai JSX untuk factory data pengujian; tampilannya seperti XML, tetapi pada tahap pembuatan elemen kami bisa membuat keputusan kontekstual yang sesuai dengan data akhir lewat builder pattern
Ini tidak ada hubungannya dengan React atau DOM, dan juga bukan berarti hal seperti itu tidak bisa diekspresikan secara deklaratif tanpa JSX
Secara pribadi, saya lebih suka memperbarui DOM secara imperatif. Dengan begitu saya bisa mengendalikan dengan sangat rinci apa yang terjadi, dan bisa merancang struktur yang sangat efisien
Saya juga bisa membuat aplikasi mudah ditambah, diubah, dihapus, dan diperbaiki fiturnya tanpa harus memaksakan cara berpikir mengikuti metodologi kuat milik orang lain
UI=f(state)—menjadi melemah, tetapi ini terasa seperti salah satu abstraksi yang bocor paling parah di seluruh dunia komputasiAda alasan kenapa di sekitar React muncul ekosistem tentang cara agar rendering tidak terjadi berkali-kali dan cara mencegah refresh yang tidak perlu
Saya membuat proyek ini karena merasa frustrasi dengan keadaan static site generator selama 10 tahun terakhir
Karena saya kebanyakan membuat situs web statis, saya menginginkan alat yang sederhana dan intuitif, dan JSX tampak cocok, tetapi saya lelah dengan kompleksitas berlebihan dari framework JSX seperti React
Karena itu saya membuat static site generator yang merender JSX menjadi string, dan memperluasnya ke sisi browser agar JSX dirender menjadi elemen DOM terasa alami
Dalam beberapa kasus, terutama untuk layout, ini juga cocok untuk komponen bersama. Secara keseluruhan saya puas dengan hasilnya, tetapi beberapa bagian cukup hacky dan dukungan IDE juga masih bisa lebih baik
Selain itu, pendekatan ini juga cocok untuk SEO. Ini masalah yang rasanya belum benar-benar terselesaikan dengan baik di framework JSX lain
Di dokumentasi, sepertinya lebih baik menuliskan “static site generator” lengkap daripada “SSG”. Meski pernah memakai static site generator, saya tetap tidak tahu apa itu SSG sampai harus bertanya ke AI
Saya datang dari Vue dan cukup terkejut karena lit-html bisa melakukan banyak hal yang dilakukan templat Vue, termasuk pengaitan event, hanya dengan templat vanilla JS yang sederhana
Jika memakai ekstensi lit di VSCode, Anda juga bisa mendapatkan syntax highlighting dan pemeriksaan tipe penuh bahkan di dalam templat
Saya tahu soal ini setelah Marc Grabanski menulis tweet bahwa dia memakai lit-html bersama vanillajs, bukan Lit, dan setelah saya coba sendiri, hasilnya bekerja sangat baik. Ini tampak sangat mirip dengan yang sedang Anda coba selesaikan
Dengan paket templat
lit-html, Anda bisa melakukan sebagian besar hal yang dijelaskan di bagian templat: https://lit.dev/docs/templates/overview/Ini juga bisa dilakukan tanpa abstraksi komponen
lit-element: https://lit.dev/docs/libraries/standalone-templates/#renderi...Alasan “bagaimana jika” seperti ini terasa menarik adalah karena asal-usul JSX bisa ditelusuri kembali hingga XHP milik Facebook, dan XHP secara eksplisit terinspirasi oleh standar JS awal E4X, yang terlihat dan bekerja mirip dengan library yang dijelaskan di sini
[1] https://engineering.fb.com/2010/02/09/developer-tools/xhp-a-...
[2] https://en.m.wikipedia.org/wiki/ECMAScript_for_XML
Itulah juga alasan JSX bisa melampaui E4X, dan setelah itu tidak ada lagi usulan serius untuk template HTML di dalam JS
Meski begitu, tampaknya ide umumnya masih bisa dihidupkan kembali dengan sentuhan modern: https://github.com/WICG/webcomponents/issues/1069
for(of)alih-alihfor eachadalah karena E4XAlasan kita tidak mendapatkan
for (:)bahkan lebih konyol, karena itu bisa berbenturan dengan anotasi:typeyang diyakini beberapa anggota TC39 akan suatu hari masuk ke bahasa tersebut secara ajaibPernah ada yang membuat library UI dengan gagasan bahwa ekspresi template JSX benar-benar membuat node DOM nyata
Dengan mengikat objek model ke properti, sebagian boilerplate event handler imperatif juga bisa dihilangkan. Seperti yang bisa diduga, menurut saya itu ide yang bagus
https://github.com/tomtheisen/mutraction
Kita bisa menulis kode seperti membuat model dengan
track({ clicks: 0 }), lalu saat diklik menambahmodel.clicksdan langsung mencerminkan nilainya ke DOMVanJS juga layak disebut di sini: https://vanjs.org/
Library JSX lain seperti Solid.JS juga mengembalikan node DOM, dan bagus melihat ide seperti ini mulai mendapat dukungan
Menurut saya, semakin dekat ke platform yang kita pakai, semakin baik. Lapisan abstraksi kadang memang berguna, tetapi sejauh ini saya belum benar-benar menemukan kebutuhan untuk menyembunyikan platformnya
Proyek raksasa seperti milik Facebook mungkin bisa mendapat manfaat, tetapi saya belum pernah bekerja pada skala seperti itu
Contoh-contohnya memang keren, tetapi tampaknya penting bahwa mereka tidak menunjukkan props komponen yang bisa berubah seiring waktu
Kemampuan seperti itu tampaknya memang tidak dimodelkan. Jika memang tidak diperlukan, ini pendekatan yang cerdas, tetapi saya kurang bisa membayangkan bagaimana ia berkembang ke aplikasi yang lebih kompleks
Bedanya cuma penulisan 10 baris kode untuk membuat dan mengatur elemen DOM dengan cara biasa menjadi lebih ringkas
Sebenarnya, bagian yang benar-benar menarik dari framework ini justru hampir semua hal selain itu. Ada JSX yang mengembalikan string di sisi static site generator, mengambil direktori sumber mentah lalu memanipulasi
string|Buffersaat tahap SSG, serta sistem modul yang sangat efisien dan cepat buatan sendiri di ataschokidardanswcBagian memakai JSX sebagai DOM memang paling mencolok secara visual, tetapi sebenarnya lebih mirip trik pesta
Sebagai contoh, source vanillajsx.com sangat ringkas, jelas, dan pendek. Semuanya ditulis hari ini tanpa dependensi selain
imlib, dan demo JSX-as-DOM justru bagian yang paling tidak inovatif: https://github.com/sdegutis/vanillajsx.com/tree/main/siteJika Anda menyukai pendekatan JSX yang mengembalikan elemen DOM konkret seperti ini, Solid bekerja persis seperti itu, hanya saja ditambah lapisan reaktivitas yang layak
setTimeoutatausetIntervalMeski begitu, saya setuju bahwa proyek semacam ini sering bekerja baik untuk kasus penggunaan kecil, tetapi cepat runtuh dalam skenario “dunia nyata”
Implementasinya sepertinya tidak terlalu sulit
Ini sangat mirip dengan Vanilla TSX: https://github.com/wisercoder/uibuilder
Contoh aplikasi yang ditulis dengan Vanilla TSX ada di sini: https://github.com/wisercoder/eureka/tree/master/webapp/Clie...
Ini mengingatkan pada ActionScript 3, yang memiliki XML di inti bahasanya
Itu bahasa yang menyenangkan untuk ditulis, tetapi terkenal gagal menjadi ES4. Pada akhirnya, butuh lebih dari 10 tahun untuk sampai ke titik serupa lewat TypeScript dan JSX
Fitur itu dinonaktifkan untuk halaman web di Firefox 17, 6 bulan sebelum rilis pertama React
Penasaran apakah ada orang lain yang juga mengalami contoh terakhir tidak berjalan di Firefox. Di Edge berhasil, tapi di Firefox gagal
Uncaught (in promise) TypeError: Map.groupBy(...).entries().map is not a functionSaya kurang paham kenapa JSX lebih menarik dibanding dipakai seperti di bawah ini
h("div", {}, [ h("p", {}, "this is easy"), ...list.map((l) => h("li", {}, l)) ])Dengan begini, kita otomatis mendapatkan loop dan interpolasi variabel tanpa perlu compiler dan tanpa membuat sintaks baru. Akan bagus kalau ada yang bisa menjelaskan
Kalau mau adil, di JSX pun loop biasa dan interpolasi tetap dipakai apa adanya.
{}menerima ekspresi JS biasaHanya saja, dibutuhkan tahap kompilasi untuk menguraikan tag elemen menjadi pemanggilan
createElementCara tiap orang memproses informasi memang berbeda, tetapi contoh itu penuh tanda baca sehingga sangat sulit dipahami dengan cepat
Tanpa mengurai sintaksnya sendiri di kepala, struktur DOM yang dihasilkan tidak terlihat, dan bisa memahami struktur DOM sepintas jauh lebih penting daripada perlu compiler atau tidak
Sebagai catatan, saya neurodivergen, dan semoga penjelasan ini membantu
Mirip dengan yang terlihat di alat pengembang browser, jadi lebih mudah dibandingkan dan di-debug
Tetapi di aplikasi kompleks, saat komponen menjadi ratusan dan mulai saling diimpor dan dipakai, menulis dengan tag JSX terasa seperti sintaks yang sederhana dan mudah dipahami
Penolakan terhadap React juga pada akhirnya sering muncul karena terasa berlebihan untuk hal-hal sederhana, dan memang berlebihan
Namun aplikasi yang dibuat tiap orang, tingkat kompleksitasnya, dan kebutuhannya berbeda-beda, jadi tidak bisa disederhanakan dengan mengatakan salah satunya lebih menarik. Ini adalah alat yang berbeda untuk masalah yang berbeda