Ini JAUH lebih baik dari NextJS (TanStack Server Components)

BBetter Stack
Computing/SoftwareInternet Technology

Transcript

00:00:00React server components. Suka atau benci. Sepertinya akhir-akhir ini lebih banyak yang benci,
00:00:04tapi itu mungkin akan segera berubah karena TanStack telah masuk ke dalam permainan. Benar, sekarang kita memiliki TanStack
00:00:08server components dan mereka mengambil pendekatan yang cukup berbeda dari Next.js. Mari kita lihat.
00:00:13Sekarang saya akan mulai dengan sebuah paragraf dari postingan pengumuman mereka yang menurut saya akan membuat
00:00:21banyak orang merasa tenang. Tulisannya: "Kebanyakan orang sekarang memikirkan React server components dengan cara
00:00:26server-first. Server memiliki pohonnya, useClient menandai bagian interaktif, dan konvensi framework
00:00:31memutuskan bagaimana semuanya disatukan. Ini mengubah React server components dari sebuah
00:00:35primitif yang berguna menjadi hal yang harus diikuti oleh seluruh aplikasi Anda. Kami tidak berpikir Anda harus membeli
00:00:40model itu sepenuhnya sejak awal hanya untuk mendapatkan nilai dari React server components."
00:00:45Pada dasarnya yang mereka katakan adalah mereka tidak ingin mengikuti rute Next.js di mana
00:00:48server components menjadi bawaan dan kemudian Anda memerlukan direktif useClient di tempat yang Anda ingin memiliki
00:00:52interaktivitas. Sebaliknya, TanStack ingin berpikir tentang bagaimana jika Anda bisa menggunakan React server components
00:00:57segranular saat Anda mengambil JSON di client. Dengan tujuan itu, mari kita lihat
00:01:01bagaimana mereka sebenarnya mengimplementasikan server components karena spoiler, saya sangat menyukai cara
00:01:06mereka melakukannya. Apa yang saya miliki di sini adalah aplikasi TanStack Start normal, jadi semuanya saat ini akan
00:01:10menjadi client component dan satu-satunya hal yang telah saya lakukan adalah beberapa langkah instalasi kecil yang Anda perlukan untuk membuat
00:01:15server components berjalan, yang pada dasarnya hanya menginstal beberapa paket dan memodifikasi
00:01:18vconfig Anda. Seperti inilah tampilan halaman saat ini, kita memiliki komponen salam di sini yang
00:01:22seharusnya saat ini merupakan client component dan di dalam kodenya, itu benar-benar hanya sebuah komponen React tunggal
00:01:27lalu di bawah sini kita memiliki rute TanStack normal dan kita menggunakan komponen salam di sini. Sekarang mari
00:01:32kita katakan di komponen salam Anda ingin melakukan logika di server. Dalam kasus saya, saya ingin mendapatkan
00:01:36hostname sistem operasi lalu juga beberapa variabel lingkungan yang hanya tersedia untuk server
00:01:40hanya untuk menunjukkan kepada Anda bahwa ini benar-benar berjalan di sana. Saat ini jika saya mencoba menggunakan os.hostname
00:01:45itu tidak akan berfungsi karena ini adalah fungsi node dan tidak tersedia di browser.
00:01:49Apa yang perlu kita lakukan adalah mengambil komponen salam kita dan me-render ini di server dan
00:01:53langkah pertama untuk melakukannya di TanStack Start adalah dengan fungsi server sederhana. Seperti yang Anda lihat, saya punya
00:01:58satu di sini yang disebut get greeting dan semua yang kita lakukan di dalamnya adalah menggunakan fungsi render server
00:02:01component yang baru, memasukkan komponen kita ke dalamnya, dan mengembalikan server component yang dapat dirender
00:02:06yang kita dapatkan kembali. Anda bisa menganggap ini sesederhana membuat permintaan get untuk komponen kita.
00:02:10Selanjutnya, yang perlu kita lakukan hanyalah mengambil komponen dari fungsi server yang telah kita buat
00:02:14dan kita bisa melakukannya di dalam loader pada rute di sini, jadi kita hanya menunggu get greeting lalu
00:02:18mengembalikannya juga dan itu masih merupakan server component yang bisa dirender. Kemudian kita bisa menggunakannya di dalam
00:02:23rute kita di sini dengan menggunakan use loader data dan kita hanya menggunakan komponen di bawah sini seperti ini. Dengan begitu,
00:02:27kita sekarang memiliki TanStack server component pertama kita. Anda bisa melihat os.hostname sekarang berfungsi dan juga
00:02:32menarik variabel lingkungan yang hanya tersedia di server. Sekarang hal yang
00:02:36sangat saya sukai dari implementasi ini adalah jika Anda perhatikan, satu-satunya hal baru di sini adalah fungsi render
00:02:41server component. Sisanya hanyalah TanStack Start normal. Anda bisa mengganti ini
00:02:46dengan hanya beberapa data JSON sederhana yang dikembalikan dan Anda akan mengambilnya dengan cara yang persis sama. Saya juga berpikir
00:02:51implementasi ini sangat eksplisit tentang di mana kode Anda sebenarnya berjalan. Anda melakukannya semua
00:02:55di dalam fungsi server, jadi cukup jelas bahwa itu akan dijalankan di server dan juga
00:02:59di dalam render server component. Faktanya, saya pikir saya bisa meningkatkan kode demo saya di sini dengan hanya
00:03:03mengambil fungsi-fungsi yang kita jalankan di atas yang ingin saya jalankan di server, meletakkannya
00:03:07di dalam fungsi server, dan kemudian cukup oper nilai tersebut ke dalam komponen salam saya sebagai props, jadi
00:03:12sekarang komponen salam saya pada dasarnya hanyalah komponen biasa yang sebenarnya bisa digunakan di
00:03:16client atau server. Saya menjalankan semua logika yang ingin saya jalankan di server di dalam
00:03:21fungsi server saya di sini. Sekali lagi, cukup eksplisit bahwa itu akan berjalan di server. Ini
00:03:25benar-benar terasa seperti kebalikan dari logika yang digunakan di Next.js dan saya sangat menyukainya.
00:03:30Itu berarti saya bisa memikirkan React dengan cara biasa, semuanya client-first lalu menambahkan server components
00:03:34di atasnya saat saya menginginkannya. Tapi bagaimana jika saya ingin menggunakan client component di dalam server
00:03:38component, jadi tersarang di dalam pohon? Katakanlah saya ingin menambahkan tombol penghitung di sini yang setiap kali kita
00:03:43mengkliknya, ia hanya menambah ke penghitung. Nah, jika saya mencoba menambahkannya ke dalam server component saya di sini dengan
00:03:47on click dan juga panggilan use state, Anda bisa melihat itu benar-benar rusak. Tulisannya use state bukan
00:03:52fungsi atau nilai kembaliannya tidak dapat diiterasi dan itu karena greeting sedang digunakan sebagai server
00:03:56component. Kita tidak bisa menggunakan fungsionalitas client ini. Untuk memperbaikinya, Anda punya dua pilihan dan pilihan kedua
00:04:01jelas yang terbaik untuk digunakan, tetapi pilihan pertama akan terasa familier bagi mereka
00:04:05yang pernah menggunakan Next.js. Kita bisa dengan mudah memindahkan logika itu ke komponennya sendiri lalu menggunakan
00:04:10direktif use client. Ini berfungsi di TanStack Start server components, kita bisa dengan mudah menggunakan
00:04:14komponen di dalam server component sekarang dan seperti yang Anda lihat, semuanya berfungsi dengan baik. Sisi negatifnya
00:04:18dari pendekatan ini adalah kita sekarang memiliki server component yang mengontrol rendering dari
00:04:22client component dan ini bisa mulai menjadi sedikit berantakan, alias jika saya ingin mencari tahu di mana
00:04:28komponen penghitung saya di dalam pohon, saya akan pergi ke rute di sini dan melihat bahwa kita memiliki server
00:04:32component greeting, lalu kembali ke server component greeting dan di dalam server component melihat
00:04:37bahwa kita memiliki client component dan kekacauan ini benar-benar bisa menumpuk dan hanya membuat batas
00:04:42antara server dan client menjadi sedikit tidak jelas. Tapi TanStack tidak akan puas dengan itu. Mereka
00:04:47bertanya pada diri sendiri, bagaimana jika server tidak perlu memutuskan setiap bagian UI yang berbentuk client sama sekali?
00:04:51Dan ini membawa mereka menciptakan sesuatu yang benar-benar baru - composite components. Untuk menggunakannya, hal pertama
00:04:56yang saya lakukan adalah menghapus client component dari server component saya dan saya hanya akan menggantinya
00:05:00dengan anak-anak (children) dari komponen salam saya. Selanjutnya kita juga perlu mengubah apa yang kita kembalikan dari
00:05:05fungsi server kita di sini. Daripada mengembalikan server component yang bisa dirender, kita perlu mengembalikan
00:05:09apa yang disebut sebagai composite source. Untuk melakukan itu, kita bisa menggunakan fungsi pembantu TanStack server component kedua kita
00:05:14yaitu create composite component. Di sini kita pada dasarnya hanya membangun sebuah komponen
00:05:18di mana props di sini dianggap sebagai slot. Saya hanya menggunakan slot anak sederhana, jadi ini akan
00:05:22meneruskan apa pun yang kita jadikan anak dari composite component saya ke dalam props.children yang
00:05:27saya teruskan ke komponen salam yang baru saja kita miliki. Dengan itu, sekali lagi yang perlu kita lakukan adalah
00:05:31cukup mengambil composite component kita dari fungsi server kita dan kita melakukannya dengan cara yang persis sama di
00:05:36loader di sini. Anda lihat saya hanya menamai ulang source menjadi greeting lalu saya memuatnya dengan use loader
00:05:41data. Satu-satunya perbedaan di sini adalah kita tidak bisa menggunakan ini sebagai komponen. Anda lihat ini memunculkan
00:05:45kesalahan di sini. Untuk benar-benar me-render composite component, kita perlu menggunakan pembantu composite component
00:05:49yang kita dapatkan dari TanStack server components dan sebagai prop source, kita teruskan
00:05:53composite component yang kita ambil dari fungsi server yang kita buat tadi.
00:05:57Dengan begitu, server component saya sekarang me-render seperti yang kita miliki sebelumnya dan saya juga meneruskan
00:06:01penghitung sebagai anak dari composite component ini dan itu diteruskan ke greeting di mana kita
00:06:05memilikinya diatur di sini, jadi itu meneruskannya ke props.children, sehingga semuanya sekarang berfungsi
00:06:10dengan baik. Saya juga bisa masuk ke komponen penghitung saya dan menghapus direktif yang kita miliki di sini karena itu
00:06:14tidak lagi diperlukan karena ia tahu ini akan menjadi client component karena berada di dalam composite
00:06:18component. Ini digunakan sebagai slot. Sekarang mungkin tampak seperti kita mendapatkan hasil yang sama
00:06:23di sana tetapi dengan lebih banyak pekerjaan daripada sekadar menggunakan direktif use client, namun kekuatannya benar-benar datang dari
00:06:27pengalaman pengembang dan ini sedikit berbeda dari model use client. Alih-alih server kita memutuskan
00:06:32di mana client components kita dirender seperti ketika kita memiliki komponen penghitung di dalam
00:06:36server component itu sendiri, alih-alih yang kita lakukan dengan composite components adalah mengatakan hey,
00:06:40akan ada slot di sini, kita akan me-render client component di dalamnya, tetapi server
00:06:44component itu sendiri tidak tahu apa itu nantinya. Kita menambahkannya nanti di dalam kode client kita,
00:06:48jadi kita menangani semua komponen berbasis client di dalam kode client itu sendiri. Itu baru permulaan juga,
00:06:53jika kita melihat halaman yang lebih kompleks seperti halaman postingan ini di mana postingan ini di-render di server,
00:06:58ada dua masalah yang ingin saya selesaikan. Yang pertama adalah saya ingin menambahkan beberapa tindakan seperti
00:07:03menyukai postingan dan mengikuti penulisnya, tapi saya ingin menambahkannya di atas judul di sini dan saya ingin
00:07:08menggunakan client component. Saat ini saya hanya menggunakan pola slot anak, itu berarti jika saya
00:07:12menambahkan tindakan postingan saya di bawah sini, itu hanya akan pergi ke tempat komentar berada karena begitulah cara kita
00:07:17mengatur komponennya, jadi saya ingin beberapa cara untuk memberi tahu server component saya di mana harus meletakkan spesifik
00:07:22client components. Lalu kita punya masalah kedua tentang jika saya memiliki tombol ikuti penulis. Saat ini
00:07:27halaman postingan ini sebenarnya tidak tahu siapa penulis postingannya. Kita sebenarnya telah memindahkan semua logika itu ke
00:07:32server component itu sendiri. Jika saya ingin mendapatkan penulis di client component di bawah sini, saya harus
00:07:37mengambil JSON untuk postingan dan mendapatkan penulis dengan cara itu dan itu bukan pola yang bagus,
00:07:42kita akan mengambil data dua kali. Untungnya bagi kita, TanStack sebenarnya memiliki dua jenis slot lain
00:07:46yang bisa kita gunakan pada composite component selain yang anak ini, dan yang pertama adalah
00:07:50render props. Ini pada dasarnya hanyalah prop apa pun yang merupakan fungsi yang mengembalikan elemen react, jadi
00:07:56ini bisa dipanggil apa saja, tidak harus dipanggil render actions dan di sini saya hanya mengatakan data apa
00:07:59yang saya ingin server component teruskan dan itu adalah id postingan dan id penulis.
00:08:04Sekarang yang perlu kita lakukan di composite component kita hanyalah menggunakan fungsi yang kita teruskan
00:08:08sebagai prop di mana pun Anda ingin komponen yang pada akhirnya akan dirender berada.
00:08:12Dalam kasus saya, saya ingin itu berada di bawah header kartu, jadi saya bisa memanggilnya dengan props.render
00:08:16actions, kita bisa menggunakan opsional, jadi jika tidak diteruskan, itu tidak akan rusak, hanya tidak akan
00:08:20di-render, lalu kita juga bisa meneruskan informasi yang kita inginkan dari server component
00:08:24ke client component kita. Setelah ini, composite component kita akan menerima prop render actions
00:08:28yang baru saja kita buat dan untuk nilainya, kita cukup meneruskan fungsi yang memiliki id postingan
00:08:32dan id penulis sebagai argumen yang akan diisi oleh server, lalu kita cukup me-render client component
00:08:36tindakan postingan dan kita bisa meneruskan data itu sebagai props. Jadi sekarang saya punya tombol
00:08:41di atas sini di mana saya bisa menyukai dan menyalin tautan ke postingan dan juga mengeklik ikuti penulis di sini di mana
00:08:45ia sadar akan nama penulisnya meskipun faktanya saya sebenarnya tidak pernah mengambilnya di halaman ini.
00:08:49Saya hanya mengambilnya di server component dan server component meneruskan data itu ke
00:08:53client component untuk saya. Sekarang Anda mungkin berpikir ini merusak logika yang kita miliki sebelumnya di mana kita mengatakan
00:08:57kita tidak ingin server component apa pun yang bertanggung jawab me-render yang client, tetapi tidak, dan itu
00:09:01karena slot sebenarnya buram. Server component di atas sini tidak tahu apa yang ada di dalam
00:09:06ini, ia hanya tahu bahwa sesuatu ada di sini dan itu perlu meneruskan nilai-nilai ini yang di
00:09:10kasus ini adalah id postingan dan id penulis. Fungsi ini tidak berjalan di server, sebaliknya
00:09:15server hanya melihat bahwa ia perlu meneruskan data, lalu di client kita, inilah saat
00:09:19fungsinya benar-benar dijalankan dan komponennya dirender. Hal yang persis sama juga berlaku untuk
00:09:23jenis slot ketiga kita, yaitu component props, yang satu ini sebenarnya sedikit lebih sederhana daripada
00:09:28render props. Semua yang kita lakukan adalah, alih-alih memiliki fungsi yang kemudian mengembalikan client component kita,
00:09:33kita hanya meneruskan client component sebagai prop itu sendiri, lalu pada composite component
00:09:38kita di atas sana, kita mengatakan bahwa kita ingin menerima prop yang merupakan komponen react yang memiliki
00:09:42props id postingan dan id penulis, lalu kita bisa menggunakan ini di dalam komponen itu sendiri. Anda bisa menganggap
00:09:47component props seperti placeholder, server component tahu akan ada komponen
00:09:51di sana yang membutuhkan beberapa data, dalam kasus kita id postingan dan id penulis, tetapi tidak benar-benar peduli apa komponen itu
00:09:56selama ia menerima props tersebut, jadi saya mengubah komponen tindakan postingan saya di bawah sini menjadi
00:10:01yang lain yang saya buat bernama fake post actions dan kemudian kita simpan, Anda bisa melihat bahwa ini
00:10:05tetap akan dirender karena client-lah yang bertanggung jawab untuk me-render komponen ini,
00:10:10hanya server yang menyediakan datanya. Melihat dokumentasinya, sepertinya tidak ada
00:10:14perbedaan nyata dalam pendekatan mana yang Anda ambil, apakah Anda memilih component props atau render props,
00:10:18itu mungkin hanya masalah preferensi, satu-satunya perbedaan yang bisa saya lihat adalah mungkin Anda ingin
00:10:22memodifikasi data yang Anda dapatkan dari server, jadi dalam kasus ini kita bisa melakukan apa pun yang kita inginkan dengan
00:10:26id postingan dan id penulis karena itu hanya fungsi dan kemudian kita bisa meneruskannya ke komponen kita,
00:10:31sedangkan jika Anda menggunakan component props, Anda hanya meneruskan komponen itu sendiri dan server
00:10:36menangani penerusan props. Nah itu dasar-dasar TanStack server components tetapi masih ada
00:10:40banyak lagi yang disukai, misalnya jika Anda ingin sebagian besar halaman Anda di-render di server,
00:10:44mungkin Anda memiliki komponen header, komponen konten, dan satu footer dan Anda ingin semuanya di-render
00:10:49di server, Anda tidak harus membundel semuanya ke dalam satu fungsi render server component. Anda sebenarnya bisa
00:10:53menggunakan promise.all, memisahkannya ke dalam tiga fungsi berbeda, dan kemudian cukup mengembalikannya sebagai objek
00:10:58dari satu fungsi server. Tapi bagaimana jika salah satu dari komponen itu lama dimuat, itu akan
00:11:03berarti seluruh fungsi server akan, dan karena itu seluruh halaman akan. Nah, jangan khawatir di sana juga,
00:11:07apa yang sebenarnya bisa kita lakukan adalah alih-alih menunggu fungsi render server component, kita sebenarnya bisa
00:11:12mengembalikan promise yang dibuatnya dan kemudian di client, kita bisa memanfaatkan hook use dan
00:11:16batas suspense untuk memuat skeleton, jadi server components hanya akan memuat saat sudah siap.
00:11:21Saya benar-benar menyukai pendekatan yang diambil TanStack di sini, itu tidak terasa mengganggu, saya tidak dipaksa
00:11:25untuk mengadopsinya dan saya bisa mengadopsinya tanpa solusi aneh. Ditambah lagi saat saya benar-benar menggunakannya,
00:11:31server components itu sendiri sebenarnya hanya tiga fungsi baru, sisanya hanyalah fungsi server TanStack Start sederhana,
00:11:36sesuatu yang sudah saya gunakan dan sesederhana mengambil
00:11:41data. Ini juga berarti ia terintegrasi dengan baik dengan alat seperti TanStack Query, sesuatu yang akan saya
00:11:45pasti lakukan, dan itu juga membuat hal-hal seperti caching menjadi lebih sederhana. Jika Anda mau, Anda benar-benar bisa
00:11:49hanya meng-cache respons dari permintaan get di CDN Anda. Saya pasti akan mengeksplorasi ini lebih lanjut,
00:11:54jadi beri tahu saya di komentar di bawah apa pendapat Anda tentang ini dan jika Anda ingin melihat lebih banyak video tentangnya,
00:11:59yah, subscribe dan seperti biasa, sampai jumpa di video berikutnya.

Key Takeaway

TanStack Server Components menawarkan pendekatan fleksibel yang memungkinkan pengembang memilih penggunaan komponen server secara granular tanpa harus mengikuti struktur server-first yang kaku seperti di Next.js.

Highlights

TanStack Server Components memungkinkan penggunaan komponen server secara granular tanpa harus mengadopsi model server-first di seluruh aplikasi.

Implementasi server components di TanStack Start hanya memerlukan fungsi renderServerComponent baru dan tidak mengubah alur kerja standar.

Composite components memungkinkan pemisahan antara rendering di server dan penempatan komponen klien melalui sistem slot yang transparan.

Data dapat diteruskan secara aman dari server ke komponen klien menggunakan render props atau component props tanpa memerlukan pengambilan data ganda.

Promise dari fungsi render server dapat dikembalikan langsung ke klien untuk memanfaatkan hook use dan suspense, sehingga memungkinkan pemuatan skeleton UI secara efisien.

Timeline

Pendekatan TanStack terhadap Server Components

  • TanStack tidak mewajibkan penggunaan server components sebagai bawaan di seluruh aplikasi.
  • Model ini memungkinkan penggunaan server components secara granular layaknya mengambil data JSON di klien.

Berbeda dengan model server-first yang mengharuskan penggunaan direktif useClient untuk interaktivitas, TanStack memungkinkan integrasi server components secara opsional. Tujuannya adalah memberikan nilai tambah tanpa memaksa pengembang mengubah seluruh arsitektur aplikasi sejak awal.

Implementasi Dasar Server Components

  • Instalasi melibatkan penambahan beberapa paket dan modifikasi vconfig.
  • Fungsi renderServerComponent memungkinkan eksekusi logika server langsung dari dalam loader.
  • Penggunaan komponen tetap eksplisit karena logika berjalan di dalam fungsi server atau fungsi render server component.

Pengembang dapat menjalankan logika node-only seperti os.hostname di server dengan mengembalikan hasil render ke klien. Implementasi ini bersifat eksplisit, di mana kode server terpisah dari komponen UI biasa yang dapat digunakan di klien maupun server.

Penggunaan Composite Components

  • Composite components menghilangkan kebutuhan akan direktif useClient secara langsung di dalam server components.
  • Sistem slot memungkinkan server merender layout sementara klien menangani komponen interaktif di dalamnya.
  • Logika interaktif seperti state management tetap ditangani sepenuhnya di kode klien.

Pendekatan ini menyelesaikan masalah tumpang tindih antara komponen klien dan server. Server tidak perlu mengetahui detail UI klien; ia hanya menyediakan slot, sehingga batas antara kedua sisi menjadi lebih bersih dan tidak berantakan.

Pengaturan Data Lanjut dengan Render Props dan Component Props

  • Render props memungkinkan penerusan data server ke klien tanpa pengambilan data ganda.
  • Component props berfungsi sebagai placeholder yang menerima data dari server tanpa bergantung pada implementasi spesifik komponen.
  • Slot bersifat buram bagi server, sehingga data diteruskan tanpa server mengetahui secara spesifik komponen apa yang akan dirender di klien.

TanStack menyediakan mekanisme untuk meneruskan ID postingan atau penulis langsung dari server ke komponen klien melalui props. Baik menggunakan fungsi (render props) maupun komponen itu sendiri (component props), data mengalir dari server ke klien dengan efisien tanpa merusak logika aplikasi.

Optimasi Pemuatan dan Integrasi

  • Promise.all dapat digunakan untuk memisahkan logika server dari berbagai bagian halaman guna menghindari bottleneck.
  • Hook use dan suspense dapat menangani skenario pemuatan lambat dengan menampilkan skeleton UI.
  • Integrasi dengan TanStack Query memungkinkan caching respons di level CDN.

Pendekatan ini memberikan fleksibilitas tinggi bagi pengembang untuk menangani komponen dengan waktu muat berbeda. Selain itu, caching respons menjadi lebih sederhana karena output server components dapat dikelola layaknya permintaan GET standar.

Community Posts

No posts yet. Be the first to write about this video!

Write about this video