Kenapa `use client` Kamu Sering Bikin Error di Nextjs Tips Fix Hydration Cuma 5 Menit
Kalau kamu adalah developer yang lagi asyik nge-coding pakai Next.js App Router (Next 13 ke atas), pasti sudah akrab banget sama yang namanya use client. Itu lho, mantra sakti yang kita taruh di baris paling atas file komponen buat bilang, "Hei, komponen ini harus dijalankan di sisi browser, ya!"
Next.js dengan arsitektur React Server Components (RSC) memang keren banget, bikin performa aplikasi kita ngebut karena banyak rendering dilakukan di server. Tapi, begitu kita pakai use client, kadang-kadang muncul error yang bikin pusing tujuh keliling, utamanya si biang kerok: Hydration Mismatch.
Di Javapixa Creative Studio, kami sering banget ketemu kasus ini. Jadi, kami putuskan buat kasih kamu insight kenapa ini terjadi dan, yang paling penting, tips fix Hydration Mismatch dalam waktu singkat. Anggap saja ini sesi konsultasi kilat, santai tapi tetap powerful.
---
Kenalan Lebih Dekat dengan Biang Kerok: Hydration Mismatch
Sebelum kita bahas fix-nya, mari kita pahami dulu kenapa use client itu sering ribut sama Next.js.
Konsepnya begini: Ketika kamu menggunakan App Router, secara default semua komponen adalah Server Components. Mereka di-render (diproses) di server dan hasilnya (berupa HTML murni) langsung dikirim ke browser pengguna. Ini yang bikin initial load cepat.
Hydration adalah proses di mana React di browser mengambil HTML yang sudah dikirim dari server, lalu "menghidupkannya" dengan memasang event listeners dan mengaktifkan state React. Ibaratnya, server mengirimkan cetakan kue (HTML), dan browser memberikan hiasan gula-gula (JavaScript interaktif).
Hydration Mismatch terjadi saat cetakan kue yang dikirim server tidak sama dengan hasil akhir kue yang diharapkan oleh React di browser.
Kenapa bisa beda? Karena komponen yang kamu tandai use client punya dua fase rendering krusial:
- Server Render: Next.js mencoba me-render komponen tersebut di server dulu untuk mendapatkan HTML awal (Initial HTML).
- Client Render/Hydration: Komponen di-render lagi di browser, kali ini dengan full akses ke JavaScript dan browser APIs.
Jika output dari Fase 1 dan Fase 2 berbeda, maka BAM! Next.js teriak, "Ada perbedaan! Ini Mismatch!" dan aplikasimu bisa error.
---
3 Penyebab Utama use client Bikin Rusuh dan Cara Memperbaikinya
Next.js dan React sangat sensitif terhadap output HTML. Kalau ada satu spasi saja yang beda, mereka sudah curiga. Tapi, biasanya ada tiga alasan utama yang selalu muncul dan bisa kamu fix dalam 5 menit.
1. Mengakses Browser APIs Tanpa Pengamanan
Ini adalah penyebab paling umum. Komponen yang kamu tandai use client mungkin saja mencoba mengakses objek global yang hanya ada di browser (seperti window, localStorage, atau document) pada saat ia sedang di-render di server.
Ingat, meskipun komponen itu adalah Client Component, Next.js tetap mencoba menjalankannya sebagian di server untuk SSR. Kalau di tengah jalan server menemukan kode yang memanggil window.innerWidth, server akan bingung (karena server tidak punya window) atau malah mengembalikan nilai yang berbeda.
Tips Fix Cepat (The useEffect Trick):
Solusinya adalah memastikan kode yang berinteraksi dengan browser APIs HANYA dijalankan setelah proses hydration selesai. Kita bisa memanfaatkan useEffect yang hanya berjalan di sisi client.
Kasus Awal yang Error:
javascript
'use client';const UkuranLayar = () => {
// Ini akan dieksekusi saat SSR (Server Side Render), menyebabkan mismatch
const width = window.innerWidth;
return Lebar: {width}px;
}Fix Cepat 5 Menit:
Kita gunakan state dan useEffect untuk menunda akses ke window sampai komponen terpasang di browser.
javascript
'use client';
import { useState, useEffect } from 'react';const UkuranLayar = () => {
const [lebar, setLebar] = useState(0);
const [isMounted, setIsMounted] = useState(false);useEffect(() => {
// 1. Set status mount
setIsMounted(true);
// 2. Akses window hanya di sini (Client-side only)
setLebar(window.innerWidth);// Tambahkan listener resize jika perlu
const handleResize = () => setLebar(window.innerWidth);
window.addEventListener('resize', handleResize);return () => {
window.removeEventListener('resize', handleResize);
};
}, []);// Pastikan render awal di server tidak menghasilkan konten yang mengakses window
if (!isMounted) {
// Tampilkan placeholder yang sama antara server dan client (misalnya 0)
return Lebar: 0px (Loading...);
}return Lebar: {lebar}px;
};Dengan cara ini, server akan me-render placeholder (Lebar: 0px), dan client akan me-render placeholder yang sama. Setelah hydration selesai, useEffect akan berjalan, mengambil nilai window.innerWidth yang sebenarnya, dan melakukan re-render tanpa memicu mismatch.
2. Output Berbeda Berdasarkan Waktu atau Data yang Belum Siap
Masalah lain sering muncul ketika kamu menggunakan fungsi waktu (misalnya new Date()) atau random number di dalam komponen yang di-render oleh server dan client.
Server akan me-render jam 10:00:00. Browser mungkin baru mulai hydration satu detik kemudian, jam 10:00:01. Karena angkanya beda, terjadilah mismatch.
Tips Fix Cepat (Conditional Rendering dengan Kunci unik):
Sama seperti trik sebelumnya, kuncinya adalah menunda rendering elemen dinamis sampai browser benar-benar siap.
Jika kamu menggunakan library pihak ketiga yang output HTML-nya tidak stabil (misalnya library slider atau chart yang bergantung pada ukuran container), gunakan Dynamic Imports.
Dynamic Imports (Solusi Jitu untuk Library):
Jika kamu mengimpor komponen dari library yang hanya bisa berjalan di client (misalnya komponen map interaktif), jangan impor secara statis. Gunakan next/dynamic dengan opsi ssr: false. Ini secara eksplisit memerintahkan Next.js untuk tidak mencoba me-render komponen ini di server.
javascript
// Di file komponen parent (Server Component atau Client Component)import dynamic from 'next/dynamic';// Komponen Peta ini hanya akan di-load dan di-render di sisi client
const PetaClient = dynamic(() => import('./PetaInteraktif'), {
ssr: false, // JANGAN render komponen ini di server
loading: () => Memuat peta...,
});const HalamanKita = () => {
return (
Halaman Kita
);
};Menggunakan ssr: false adalah cara paling ampuh untuk mengatasi mismatch yang disebabkan oleh library eksternal yang tidak mendukung SSR. Di Javapixa Creative Studio, kami selalu merekomendasikan ini sebagai solusi pertama untuk integrasi widget pihak ketiga.
3. Struktur HTML yang Dimanipulasi oleh Browser atau Library
Next.js sangat sensitif terhadap perbedaan tag HTML. Kadang-kadang, error bukan datang dari kode kita, melainkan dari cara browser atau library pihak ketiga memproses DOM.
Contoh: Browser (terutama Chrome atau Safari) punya kebiasaan otomatis menambahkan tag jika kamu membuat table tanpa mendefinisikannya secara eksplisit.
Server Render:
...
Client Render (setelah browser* inject |
):
| ... Karena outputnya beda, Hydration Mismatch terjadi. Tips Fix Cepat (Auditing Output & Structural Debugging):
|