React Compiler: Memoisasi Otomatis Tanpa useMemo

Foto oleh Markus Spiske on Pexels
React Compiler adalah compiler pengoptimasi build-time, dahulu disebut React Forget, yang secara otomatis memoisasi komponen React dan nilai hook. Ia menyisipkan padanan useMemo, useCallback, dan React.memo saat build, sehingga Anda jarang perlu menulisnya sendiri. Versinya mencapai 1.0 stabil pada 7 Oktober 2025.
Dalam banyak kasus, tidak. Compiler menyimpulkan dependensi dari alur data dan memoisasi otomatis, sering kali lebih presisi daripada kode buatan tangan. Anda tetap bisa memakai useMemo dan useCallback sebagai escape hatch yang disengaja, dan tim React menyarankan mempertahankan memoisasi lama sampai tes membuktikannya redundan.
Pasang babel-plugin-react-compiler sebagai dependensi dev, lalu atur reactCompiler menjadi true di next.config. Next.js menjalankan pass SWC yang hanya memberi berkas berisi JSX atau Hooks ke plugin Babel, sehingga build tetap cepat. Anda juga bisa memakai mode anotasi dengan direktif use memo untuk opt-in bertahap.
Memoisasi otomatis hanya aman jika komponen murni dan dapat diprediksi. Compiler mengasumsikan komponen dan hook idempoten selama render, Anda tak pernah memutasi props atau state, dan hook dipanggil hanya di tingkat teratas. Aturan lint berbasis compiler di eslint-plugin-react-hooks menangkap pelanggaran sebelum menimbulkan masalah.
Ya. React Compiler 1.0 sudah stabil dan berjalan di produksi pada aplikasi terbesar Meta. Peringatan utamanya, jika kode Anda melanggar Rules of React dengan cara yang tak terdeteksi linter, perubahan memoisasi bisa memengaruhi perilaku, jadi kunci versi persis dan pertahankan tes end-to-end saat mengadopsinya.

Foto oleh Markus Spiske on Pexels
Ringkasan Utama
React Compiler adalah compiler pengoptimasi build-time milik React yang secara otomatis memoisasi komponen dan nilai hook, sehingga developer jarang membutuhkan useMemo, useCallback, atau React.memo. Ia mencapai versi stabil 1.0 pada Oktober 2025, bergantung pada Rules of React demi keamanan, dan terintegrasi dengan Babel, Vite, dan Next.js.
Selama satu dekade, menjaga aplikasi React tetap cepat berarti menyebar useMemo, useCallback, dan React.memo di seluruh pohon komponen untuk mencegah nilai dan komponen dibuat ulang pada setiap render. Cara itu berhasil, tetapi manual, mudah keliru, dan berisik. Lupa satu dependensi dan Anda menyimpan data usang; tambah satu terlalu banyak dan memo itu tak berguna selain memakan memori.
React Compiler, yang dulu dikenal secara internal sebagai React Forget, menggantikan sebagian besar pekerjaan manual itu. Ia adalah compiler build-time yang menganalisis komponen dan hook Anda lalu menyisipkan memoisasi secara otomatis. Saya sudah mengikutinya sejak masa eksperimental, dan dengan rilis stabil 1.0 akhirnya ini menjadi sesuatu yang saya gunakan pada proyek baru secara default, bukan lagi sekadar percobaan.
Compiler berjalan sebagai bagian dari proses build, bukan di browser. Ia membaca tiap komponen, menentukan nilai mana bergantung pada input mana, lalu memancarkan kode setara yang memakai ulang nilai yang sudah dihitung ketika input tidak berubah. Hasilnya berperilaku seolah Anda menulis panggilan useMemo dan useCallback yang sempurna dengan tangan, tetapi Anda tidak menulis satu pun.
Ia juga melakukan hal yang sulit dicapai memoisasi manual. Karena compiler memahami alur kendali, ia bisa memoisasi nilai yang muncul setelah early return atau di dalam kondisi, yang dilarang oleh Rules of Hooks untuk Anda lakukan sendiri. React Compiler 1.0 diterbitkan pada 7 Oktober 2025, bekerja dengan React 17 ke atas, dan sudah berjalan di produksi pada aplikasi terbesar Meta jauh sebelum menjadi stabil.
# Install the compiler's Babel plugin (pin the exact version)
npm install --save-dev --save-exact babel-plugin-react-compiler@latest
# Compiler-powered lint rules ship inside eslint-plugin-react-hooks
npm install --save-dev eslint-plugin-react-hooks@latest
# babel.config.js — the compiler must run FIRST in the plugin pipeline
module.exports = {
plugins: [
"babel-plugin-react-compiler",
// ...other plugins
],
};Cara paling jelas merasakan perbedaannya adalah melihat sebuah komponen dalam dua gaya. Di kiri adalah gaya defensif yang ditulis kebanyakan tim hari ini; di kanan adalah logika yang sama setelah compiler diaktifkan. Perilaku runtime-nya sama, tetapi versi kedua hanyalah deskripsi polos dari apa yang dilakukan komponen itu.
// BEFORE — hand-written memoization to stop needless re-renders
function ProductList({ products, query }) {
const filtered = useMemo(
() => products.filter((p) => p.name.includes(query)),
[products, query]
);
const onSelect = useCallback((id) => track(id), []);
return <List items={filtered} onSelect={onSelect} />;
}
// AFTER — with the React Compiler enabled, you write plain code.
// The compiler inserts equivalent memoization at build time.
function ProductList({ products, query }) {
const filtered = products.filter((p) => p.name.includes(query));
const onSelect = (id) => track(id);
return <List items={filtered} onSelect={onSelect} />;
}Compiler tidak bersifat semua-atau-tidak sama sekali. Ia memancarkan direktif use memo pada kode yang dioptimasinya, dan Anda bisa menjalankannya dalam mode anotasi sehingga hanya komponen yang Anda ikutsertakan secara eksplisit yang dikompilasi. Itu membuat peluncurannya aman satu direktori demi satu direktori pada basis kode besar.
Memoisasi otomatis hanya aman jika komponen Anda dapat diprediksi. Compiler mengasumsikan kode Anda mengikuti Rules of React: komponen dan hook harus murni dan idempoten selama render, Anda tidak boleh memutasi props atau state, dan hook hanya dipanggil di tingkat teratas. Ketika itu terpenuhi, menyimpan sebuah hasil dan memakainya ulang dijamin menghasilkan keluaran yang sama.
Inilah mengapa cerita linting penting. Aturan berbasis compiler kini dikirim di dalam eslint-plugin-react-hooks, pada preset recommended-nya, sehingga Anda tidak lagi memasang plugin terpisah. Aturan seperti set-state-in-render, set-state-in-effect, dan akses ref yang tidak aman menangkap pola persis yang membuat memoisasi otomatis tidak aman, sebelum compiler menyentuh kode Anda.
Jika kode Anda melanggar Rules of React dengan cara yang tidak bisa dideteksi linter, compiler mungkin tetap mengubah seberapa sering effect berjalan atau nilai dihitung ulang. Itulah risiko sesungguhnya. Kunci versi compiler secara persis, pertahankan tes end-to-end, dan baca panduan adopsi bertahap sebelum menghapus memoisasi yang ada dari jalur kritis.
Paket intinya adalah babel-plugin-react-compiler, dan ia harus berjalan pertama di pipeline Babel Anda agar melihat sumber sebelum transform lain menulisnya ulang. Integrasi framework membungkus ini untuk Anda. Di Next.js Anda cukup mengaktifkan satu flag reactCompiler, dan Next menjalankan pass SWC yang hanya memberi berkas berisi JSX atau Hooks ke plugin Babel, sehingga build tetap cepat. Vite memakai preset react compiler, dan Expo SDK 54 ke atas mengaktifkannya secara default.
// next.config.ts — Next.js runs the compiler through Babel,
// but uses an SWC pass so only files with JSX or Hooks are compiled.
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
reactCompiler: true,
};
export default nextConfig;
// Opt-in mode: compile only components/hooks you mark with a directive
const optInConfig: NextConfig = {
reactCompiler: { compilationMode: "annotation" },
};
// then add "use memo" at the top of a chosen component or hookCompiler tidak membuat memoisasi manual ilegal; ia membuatnya sebagian besar tidak perlu. Berikut perbandingan kedua pendekatan pada hal yang benar-benar penting sehari-hari.
| Aspek | Memoisasi manual | React Compiler |
|---|---|---|
| Siapa yang menulis | Anda, dengan tangan, di setiap jalur panas | Build, otomatis, di mana saja |
| Array dependensi | Anda yang merawat dan mudah keliru | Disimpulkan compiler dari alur data |
| Nilai kondisional dan pasca-return | Tak bisa dimemoisasi; dilarang Rules of Hooks | Dimemoisasi benar di semua cabang |
| Mode kegagalan | Data usang atau memori terbuang dari deps buruk | Melewati kode yang melanggar Rules of React |
Pedoman saya setelah merilis dengannya: aktifkan compiler dan aturan lint recommended pada kode baru, biarkan ia memiliki memoisasi, dan pertahankan useMemo yang Anda andalkan sampai tes membuktikannya redundan. Perlakukan useMemo dan useCallback sebagai escape hatch yang disengaja, bukan sikap default, dan komponen Anda menjadi jauh lebih mudah dibaca.