Langsung Praktik Cara Mengatasi Hydration Error karena LocalStorage Next Js dengan State Netral

Render state awal netral dulu, lalu baca localStorage di dalam useEffect dan tampilkan nilainya setelah komponen mounted. Cara ini menyamakan HTML hasil render server dengan render pertama browser, sehingga pesan hydration mismatch hilang. Langkah yang paling sering terlewat adalah tetap memasang nilai awal kosong atau bawaan saat render pertama.

Penyebab Hydration Error saat Baca localStorage

Server tidak punya localStorage. Browser punya. Kalau render pertama memakai isi simpanan browser, hasilnya beda dari HTML server.

  • State awal memanggil localStorage.getItem langsung saat render.
  • Komponen membaca tema, token, bahasa, atau preferensi sebelum mounted.
  • Render memakai nilai acak, jam, atau data browser lain yang tidak ada di server.

Tabel Diagnosis Cepat Hydration Mismatch

Gejala Pemicu Arah Perbaikan
Teks berubah setelah refresh Tema dari localStorage Gunakan state netral plus guard mounted
Error hanya setelah login Token dibaca saat render Baca token di useEffect, tampilkan loading netral
Beda tiap render Date.now atau Math.random Pindah ke useEffect atau ke server

Pola Aman Pakai localStorage di Client Component

  1. Buat state awal netral, misalnya string kosong atau tema bawaan.
  2. Baca localStorage hanya di dalam useEffect.
  3. Tambah flag mounted, render konten tersimpan setelah nilainya true.
"use client";
import { useEffect, useState } from "react";

export default function ThemeLabel() {
  const [theme, setTheme] = useState("light");
  const [mounted, setMounted] = useState(false);

  useEffect(() => {
    const saved = localStorage.getItem("theme");
    if (saved === "dark" || saved === "light") {
      setTheme(saved);
    }
    setMounted(true);
  }, []);

  if (!mounted) {
    return 

Memuat tampilan...

; } return

Tema aktif: {theme}

; }
  • Jangan panggil window, document, atau localStorage saat render.
  • Jangan menganggap use client otomatis mencegah hydration error.
  • Simpan perubahan kembali dengan localStorage.setItem dari event atau effect.

FAQ

Kenapa localStorage memicu hydration error padahal sudah pakai use client?

Client Component tetap dirender awal oleh server, sehingga bacaan browser saat render membuat HTML berbeda.

Apakah aman cek typeof window saat render untuk ambil localStorage?

Tidak aman karena server dan browser tetap dapat menghasilkan output berbeda dan mismatch berlanjut.

Bagaimana menampilkan data tersimpan tanpa kedip tampilan?

Tampilkan kerangka netral yang ukurannya sama, lalu ganti dengan nilai tersimpan setelah mounted.