Hook React adalah fitur yang muncul setelah fiber, sehingga banyak orang yang secara keliru percaya bahwa hook harus bergantung pada fiber untuk dapat diimplementasikan.
Sekarang, hook tidak hanya diimplementasikan di react, tetapi juga di framework seperti preact, react ssr, dan midway. Implementasinya tidak bergantung pada fiber.
Mari kita lihat bagaimana hook dalam kerangka kerja yang berbeda ini diimplementasikan:
React mendeskripsikan antarmuka melalui jsx, yang akan dikompilasi menjadi fungsi render dengan alat kompilasi seperti babel atau tsc, dan kemudian dieksekusi untuk menghasilkan vdom:
Fungsi render di sini adalah React.createElement sebelum React17:
Setelah React 17, diubah menjadi jsx:
Jsx-runtime ini akan diperkenalkan secara otomatis, dan tidak perlu mempertahankan impor React untuk setiap komponen seperti sebelumnya.
Eksekusi fungsi render menghasilkan vdom:
Struktur vdom adalah seperti ini:
Sebelum React16, vdom ini akan dirender secara rekursif, menambah, menghapus, dan memodifikasi dom asli.
Setelah React16 memperkenalkan arsitektur fiber, ada langkah tambahan: pertama ubah vdom menjadi fiber, lalu render fiber.
Proses mengubah vdom menjadi fiber disebut rekonsiliasi, dan proses akhir penambahan, penghapusan, dan modifikasi dom asli disebut komit.
Mengapa kita perlu melakukan konversi seperti itu?
Karena vdom hanya memiliki referensi ke anak node anak, dan tidak ada referensi ke node induk dan node saudara lainnya, hal ini mengakibatkan kebutuhan untuk merender semua node vdom ke dom secara rekursif pada satu waktu tanpa mengganggu.
Apa yang terjadi jika terputus? Karena node induk dan node saudara tidak dicatat, kami hanya dapat terus memproses node anak, tetapi tidak dapat memproses bagian vdom lainnya.
Itu sebabnya React memperkenalkan struktur serat semacam ini, yang memiliki referensi seperti pengembalian node induk, node anak, node saudara, dll., yang dapat diinterupsi, karena semua node yang belum diproses dapat ditemukan setelah interupsi dan pemulihan.
Struktur simpul serat adalah sebagai berikut:
Proses ini dapat diinterupsi, dan tentu saja dapat dijadwalkan, yaitu proses penjadwalan.
Oleh karena itu, arsitektur fiber dibagi menjadi tiga tahap: schdule, rekonsiliasi (mengubah vdom menjadi fiber), dan melakukan (memperbarui ke dom).
Kait dapat digunakan dalam komponen fungsi untuk mengakses beberapa nilai, dan nilai ini disimpan di node serat.
Misalnya, 6 kait digunakan dalam komponen fungsi ini:
Lalu ada daftar tertaut dari 6 elemen yang dihafalState pada node serat yang sesuai:
Digabungkan dengan yang berikutnya:
Kait yang berbeda mengakses nilai pada elemen berbeda dari daftar tertaut dihafalState. Ini adalah prinsip kait reaksi.
Daftar tertaut ini memiliki fase pembuatan dan fase pembaruan, sehingga Anda akan menemukan bahwa implementasi akhir usexxx dibagi menjadi mountxxx dan updatexxx:
Fase mount di sini adalah membuat node kait dan merakitnya menjadi daftar tertaut:
Daftar tertaut kait yang dibuat akan ditautkan ke atribut memoridState dari node serat.
Saat memperbarui, Anda secara alami dapat mengambil daftar kait ini dari node serat:
Dengan cara ini, dalam beberapa rendering, api usexxx dapat menemukan memoridState yang sesuai pada node fiber.
Ini adalah prinsip kait reaksi. Anda dapat melihat bahwa kait tersebut disimpan pada simpul serat.
Lalu apa bedanya dengan pract?
Preact adalah kerangka kerja yang lebih ringan yang kompatibel dengan kode reaksi. Ini mendukung komponen kelas dan komponen fungsi, serta fitur reaksi seperti kait. Namun, itu tidak menerapkan arsitektur fiber.
Karena ini terutama mempertimbangkan ukuran pamungkas (hanya 3kb), bukan performa pamungkas.
Kita baru mengetahui bahwa react menyimpan daftar hook pada node fiber. Jika preact tidak memiliki node fiber, di mana daftar hook akan disimpan?
Faktanya, mudah untuk berpikir bahwa fiber hanya memodifikasi vdom untuk meningkatkan kinerja, dan tidak ada perbedaan penting dari vdom. Lalu bisakah kita menyimpan hook di vdom?
Memang benar, preact menempatkan daftar kait di vdom.
Misalnya, komponen fungsi ini memiliki 4 kait:
Implementasinya adalah mengakses hook yang sesuai di vdom:
Itu tidak membagi hook menjadi dua tahap, mount dan update, seperti reaksi, tetapi menggabungkan keduanya untuk diproses.
Seperti yang ditunjukkan pada gambar, ia menyimpan kait dalam array komponen.__kait dan mengaksesnya melalui subskrip.
Komponen ini adalah atribut pada vdom:
Artinya, nilai hooks disimpan dalam array vnode._component._hooks.
Bandingkan perbedaan antara react dan preact dalam mengimplementasikan hook:
di react, daftar hook disimpan di atribut fiberNode.memorizedState, di preact, daftar hook disimpan di atribut vnode._component._hooks.
Daftar hook di react digabungkan melalui berikutnya, dan di preact Daftar tertaut kait adalah sebuah array.
React memisahkan pembuatan dan pembaruan daftar tertaut kait
, implementasi hook tidak Mengandalkan fiber, hanya perlu mencari tempat untuk menyimpan data hook yang sesuai dengan komponennya.
Karena vdom, serat dan rendering komponen sangat terkait, mereka disimpan dalam struktur ini.
Misalnya, ketika react ssr mengimplementasikan hook, ia tidak ada di fiber atau di vdom:
Sebenarnya, selain csr, paket react-dom juga bisa melakukan ssr:
Gunakan metode render dari react- dom saat csr:
Saat ssr, gunakan metode renderToString atau metode renderToStream dari react-dom/server:
Apakah menurut Anda konversi vdom ke fiber akan dilakukan selama ssr?
Tentu saja tidak. Fiber adalah struktur yang diperkenalkan untuk meningkatkan kinerja rendering saat berjalan di browser, membuat penghitungan dapat diinterupsi, dan melakukan penghitungan saat tidak digunakan.
Render sisi server secara alami tidak memerlukan fiber.
Jika serat tidak diperlukan, di mana ia menyimpan daftar pengaitnya? vdom?
Memang bisa ditempatkan di vdom, tapi sebenarnya tidak.
Misalnya, kait useRef:
Ini adalah daftar tertaut yang digabungkan dengan yang berikutnya mulai dari firstWorkInProgressHook.
Dan firstWorkInProgressHook adalah simpul kait pertama yang dibuat dengan createHook:
Itu tidak dipasang di vdom.
Mengapa?
Karena ssr hanya perlu dirender satu kali dan tidak perlu diupdate, tidak perlu digantung di vdom.
Hapus saja daftar pengait setiap kali Anda selesai memproses pengait setiap komponen:
Oleh karena itu, saat menggunakan react ssr, hook ada di variabel global.
Bandingkan perbedaan prinsip implementasi hook di react csr dan ssr:
di csr, fiber akan dibuat dari vdom, yang digunakan untuk membuat rendering dapat diinterupsi dan meningkatkan kinerja melalui penjadwalan idle, tetapi di ssr, fiber tidak akan dirender secara langsung oleh vdom. Saat menggunakan
csr, hook disimpan ke node fiber, sedangkan saat menggunakan ssr, hook ditempatkan langsung pada variabel global, dan dihapus setelah setiap komponen diproses. Karena CSR tidak akan digunakan untuk kedua kalinya
, maka pembuatan dan update hook akan dibagi menjadi dua tahap: mount dan update, sedangkan SSR hanya akan diproses satu kali saja, dan hanya tahap pembuatan.
Prinsip implementasi hooks sebenarnya tidak rumit , yaitu, dalam konteks tertentu Simpan daftar tertaut dalam daftar tertaut, lalu api kait mengakses data terkait dari berbagai elemen daftar tertaut untuk melengkapi logikanya masing-masing. Konteks ini dapat berupa vdom, fiber, atau bahkan variabel global.
Namun, gagasan hook masih sangat populer. Kerangka kerja sisi server yang diproduksi oleh Taobao telah memperkenalkan gagasan hook:
Midway adalah kerangka kerja Node.js:
Kerangka kerja sisi server secara alami tidak memiliki struktur seperti vdom dan fiber, tetapi gagasan hooks tidak bergantung pada ini. Untuk mengimplementasikan API hooks, Anda hanya perlu menempatkan daftar tertaut dalam konteks tertentu.
Midway mengimplementasikan API yang mirip dengan react hooks:
Saya belum melihat secara spesifik di mana hook list itu ada, tapi kita sudah menguasai prinsip implementasi hooks. Selama ada konteks untuk menyimpan hook list, bisa dimana saja.
react hooks adalah fitur yang muncul setelah arsitektur react fiber. Banyak orang secara keliru percaya bahwa hooks harus diimplementasikan dengan fiber. Kami melihat penerapan hook di react, preact, react ssr, dan midway, dan menemukan hal itu ini tidak terjadi:
itu akan baik-baik saja. Jadi, apakah react hooks harus bergantung pada fiber untuk mengimplementasikannya?
Jelas tidak, ini dapat digunakan dengan fiber, vdom, variabel global, atau bahkan konteks apa pun.