Akhirnya penantian berakhir!

React, salah satu perpustakaan JavaScript yang paling banyak digunakan, akhirnya meluncurkan kandidat rilis versi 18 atau React 18 yang sangat ditunggu-tunggu. Artinya, hanya sedikit perubahan yang diharapkan dalam rilis final/stabil.

Pengetahuan tentang React diperlukan untuk memahami pembaruan React 18. Jika Anda seorang pemula, ikuti saja “artikel” ini untuk peta jalan di React.

Mari kita lihat apa yang dibawanya!

API Akar Baru

React 18 memiliki dua API root, API root lama dan yang baru.

Apa itu Root API?

Sesuai dengan dokumen resmi React, “root” adalah penunjuk ke struktur data tingkat atas React untuk melacak pohon yang akan dirender.

API Root Lama

Root API yang ada disebut ReactDOM.render. Saat ini, root melekat pada elemen DOM dan dapat diakses melalui node DOM.

Ini akan bekerja persis seperti di React 17. Namun, konsol akan mengeluarkan peringatan yang menunjukkan penghentiannya dan berpindah ke API terbaru.

import  React from 'react';
import ReactDOM from 'react-dom';
import './index.scss';
import App from './App
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);

API Akar Baru

Ia hadir dengan ReactDOM.createRoot, yang memungkinkan renderer bersamaan yang barudan merupakan pintu gerbang ke semua peningkatan yang diperkenalkan dengan Reaksi 18.

import * as ReactDOMClient from 'react-dom/client';
import App from 'App';

const container = document.getElementById('app');

// Create a root.
const root = ReactDOMClient.createRoot(container);

// Initial render: Render an element to the root.
root.render(<App tab="home" />);

// During an update, there's no need to pass the container again.
root.render(<App tab="profile" />);

Fungsi createRoot akan membuat root terlebih dahulu, lalu metode render yang akan dipanggil.

Bagaimana cara menangani hidrasi dengan Root API baru?

Hidrasi kini ditangani melalui hydrateRoot API.

import * as ReactDOMClient from 'react-dom/client';
import App from 'App';

const container = document.getElementById('app');
//Before 
// Render with hydration.
ReactDOM.hydrate(<App tab="home" />, container);
//After
// Create *and* render a root with hydration.
const root = ReactDOMClient.hydrateRoot(container, <App button="add" />);

// You can later update it.
root.render(<App button="update" />);

Render Callback dan API Root baru

Panggilan balik render dihapus karena tidak dapat mengakomodasi peningkatan yang diberikan melalui hidrasi parsial dan streaming SSR.

import * as ReactDOMClient from 'react-dom/client';

const rootElement = document.getElementById("root");
// Don't do this
ReactDOMClient.render(<App />, rootElement, () => console.log("renderered"));
// Do this
const root = ReactDOMClient.createRoot(rootElement);
root.render(<App callback={() => console.log("renderered")} />);

Sebaliknya, React merekomendasikan penggunaan requestIdleCallback, setTimeout, atau callback ref pada root.

Ringkasan perbedaan antara API root lama dan baru

  • Panggilan balik render telah dihapus, dan fungsi hidrasi berfungsi diubah.
  • Root adalah sebuah objek, dan fungsi apa pun untuk memperbarui root diterapkan pada objek ini, bukan pada DOM.

Pengelompokan Otomatis

Pernahkah Anda memperbarui beberapa status dalam satu fungsi yang dipanggil oleh pengendali peristiwa? Anda mungkin telah memperhatikan bahwa semua negara bagian diperbarui dalam satu render. Ini disebut pengelompokan otomatis.

Batching adalah saat React mengelompokkan beberapa pembaruan status ke dalam satu rendering ulang untuk kinerja yang lebih baik.

Sebelum React 18, batching hanya dilakukan di event handler React secara default.

Melanjutkan dengan Root API baru, batching dapat dilakukan terlepas dari asalnya, seperti janji, setTimeout, event handler asli. Pembaruan ini akan meningkatkan kinerja keseluruhan dan waktu rendering.

Nonaktifkan Batching Otomatis

Jika kasus penggunaan memerlukan pembaruan status dan menunggu respons sebelum melakukan tindakan lain, ReactDOM. flushSync()datang untuk menyelamatkan.

import { flushSync } from 'react-dom';

function handleClick() {
  flushSync(() => {
    // setState function
  });
  // React has updated the DOM by now
  flushSync(() => {
     // setState function
  });
  // React has updated the DOM by now
}

Rendering Sisi Server (SSR) Ketegangan/Streaming dan Hidrasi Selektif

Dalam bahasa awam, rendering sisi server mengacu pada pembuatan konten HTML di server dan disajikan ke klien hingga JavaScript dimuat dan disajikan sepenuhnya.

Kelemahan dalam Arsitektur React SSR Saat Ini

  • Seluruh JS harus dimuat sebelum hidrasi dan kemudian komponen menjadi interaktif.
  • Data, seperti panggilan API, harus sudah siap di sisi server karena tidak perlu menunggu.
  • Semua komponen harus dihidrasi sebelum berinteraksi dengannya.

Bereaksi 18 Arsitektur SSR

Tidak seperti SSR saat ini yang mengikuti pendekatan “utuh atau tidak sama sekali”, React 18 membawa perubahan revolusioner dalam hal ini dengan mengaktifkan streaming HTML, hidrasi selektif, dan komponen pemuatan lambat di SSR.

1. Streaming HTML

Membungkus komponen apa pun dengan ‹suspense›‹/suspense›akan memberitahu React untuk tidak menunggu komponen tersebut. Sebagai gantinya, HTML akan mulai streaming dan ketika data untuk kode tersebut, yang dibungkus dalam Suspense, sudah siap di server, HTML tambahan akan dikirim ke aliran yang sama dengan JS inline minimal untuk ditempatkan di tempat yang tepat.

Untuk streaming HTML di server, API renderToPipeableStream digunakan sebagai pengganti renderToString.

Ini akan membantu mengatasi masalah memiliki data yang lengkap sebelum merender apa pun.

2. Hidrasi Selektif dan Lazy Loading pada SSR

Fitur Lazy React memungkinkan pemuatan lambat di sisi klien, yaitu hanya JS dari komponen yang diperlukan yang akan dimuat, bukan keseluruhan aplikasi.

Sebelum menggunakan hidrasi selektif, Anda harus ikut serta dalam API createRoot baru.

Produk pembungkus memberitahu React untuk membuka blokir komponen lainnya dari streaming, dan tidak perlu menunggu seluruh JS dimuat sebelum hidrasi.

Saat komponen sedang dihidrasi, React akan memprioritaskan bagian layar yang paling mendesak berdasarkan interaksi pengguna.

import { lazy } from 'react';

const Products = lazy(() => import('./products.js'));

<Suspense fallback={<Spinner />}>
  <Products />
</Suspense>

API baru

1. Rendering Bersamaan

  • mulaiTransisi API

Bekerja dengan data dalam jumlah besar dan memperbarui status dalam jumlah besar sering kali memperlambat atau membekukan UI.

API startTransition hadir untuk menyelamatkan saat ia mentransisikan pembaruan status ke pembaruan yang tidak mendesak dan melakukan tugas-tugas kompleks di latar belakang. Pengalaman pengguna tetap mulus.

import { useTransition, startTransition } from 'react';
// Urgent: Show what was typed
setInputValue(input);

// Mark any state updates inside as transitions
startTransition(() => {
  // Transition: Show the results
  setSearchQuery(input);
});

Ia juga menyediakan kait useTransitionuntuk memeriksa status transisi.

import { useTransition } from 'react';

const [isPending, startTransition] = useTransition();
{isPending && <Spinner />}
  • useDeferredValue
import { useDeferredValue } from "react";
const deferredValue = useDeferredValue(text, { timeoutMs: 2000 });

Hook mengembalikan versi yang ditangguhkan dari nilai yang diteruskan. Biasanya digunakan untuk menjaga antarmuka tetap responsif ketika Anda memiliki sesuatu yang segera dirender berdasarkan masukan pengguna dan sesuatu yang perlu menunggu pengambilan data.

2. useId

useId adalah API untuk menghasilkan ID unik pada klien dan server sekaligus menghindari ketidakcocokan hidrasi.

const id = useId();
<input type="checkbox" name="react" id={id} />

Peningkatan Suspense dengan SuspenseList

SuspenseList mulai beraksi ketika beberapa komponen memerlukan pengambilan data dan pesanan yang tidak dapat diprediksi.

SuspenseList hanya beroperasi pada komponen Suspense dan SuspenseList terdekat di bawahnya. Ia tidak mencari batasan yang lebih dalam dari satu tingkat. Namun, beberapa komponen SuspenseList dapat disarangkan satu sama lain untuk membangun grid.

<SuspenseList revealOrder="forwards">
  <Suspense fallback={'Loading...'}>
    <ProfilePicture id={1} />
  </Suspense>
  <Suspense fallback={'Loading...'}>
    <ProfilePicture id={2} />
  </Suspense>
  <Suspense fallback={'Loading...'}>
    <ProfilePicture id={3} />
  </Suspense>
  ...
</SuspenseList>

Dengan SuspenseList, komponen tidak akan ditampilkan sampai komponen sebelumnya telah mengambil data dan siap.

Dibutuhkan dua props: revealOrder (maju, mundur, bersama-sama)mendefinisikan urutan komponen yang terdaftar untuk ditampilkan dan tail (diciutkan, disembunyikan) menentukan bagaimana item yang dibongkar dalam sebuah SuspenseList ditampilkan.

Ringkasan

Mengingat perubahan arsitektur yang dibawa oleh React 18, komunitas React sangat antusias. Ini akan memberikan UI, UX, CX yang lebih baik, dan aplikasi web yang lebih andal dan efisien akan segera hadir.

Pantau terus!

Mari terhubung di LinkedIn.