Berhenti pakai `useEffect` buat fetching data, Next.js punya cara baru yang lebih *clean* buat kamu
Beberapa tahun belakangan ini, kalau kita ngomongin data fetching di React atau Next.js, pasti yang langsung terlintas di kepala adalah si hero sekaligus villain kita: useEffect.
Bukan rahasia lagi, useEffect sudah jadi pondasi utama buat mengambil data saat komponen selesai di-mount. Tapi, mari jujur. Menggunakan useEffect buat fetching data awal itu rasanya kayak naik sepeda yang bannya agak kempes. Bisa sampai, tapi penuh perjuangan dan sering bikin kesel.
Kita semua tahu skenarionya: buat fetching data, kita harus pakai useEffect, di dalamnya ada fungsi async, terus kita harus mengurus loading state, error state, dan yang paling bikin pusing, kita harus memastikan kita bersih dari race condition atau memory leak (pakai cleanup function di return useEffect). Belum lagi, kalau datanya berubah, kita harus repot-repot mengatur dependency array.
Ribet, kan? Boilerplate code-nya banyak, kodenya jadi kurang clean, dan yang paling parah, ini sangat memengaruhi performa dan pengalaman pengguna (UX) karena data baru diambil setelah komponen selesai di-render di sisi klien.
Untungnya, Next.js (khususnya setelah adopsi App Router) punya solusi revolusioner yang bikin kita bisa bilang, "Selamat tinggal, useEffect sialan!" buat urusan initial data fetching. Next.js membawa kita ke era di mana fetching data dilakukan di sisi server secara default dan terintegrasi mulus.
Inilah saatnya kita benar-benar harus mengubah kebiasaan. Kita akan bahas tuntas cara paling clean dan modern untuk mengambil data di Next.js, yang mana ini adalah standar wajib buat aplikasi skala besar yang fokus pada performa dan developer experience (DX) yang canggih.
*
1. Revolusi Fetching: Server Components Adalah Kunci
Perubahan paling fundamental di Next.js App Router adalah pengenalan React Server Components (RSC). Secara default, semua komponen di App Router adalah Server Components, kecuali kamu secara eksplisit menambahkan 'use client' di bagian atas file.
Kenapa ini penting? Karena Server Components berjalan dan dieksekusi hanya di sisi server, sebelum HTML dikirim ke browser klien.
A. Fetching Langsung di Komponen
Dengan Server Components, kita bisa melupakan useEffect untuk fetching data awal. Kita bisa memperlakukan komponen layaknya fungsi asynchronous biasa yang langsung mengambil data.
Bayangkan kamu punya fungsi untuk mengambil daftar produk dari API. Di masa lalu, kamu harus mengimpor useState dan useEffect. Sekarang, kamu tinggal pakai async/await langsung di fungsi komponen kamu:
javascript
// app/produk/page.jsx (Ini adalah Server Component default)import { cache } from 'react';// Fungsi untuk fetching data (bisa di file terpisah)
const getDaftarProduk = cache(async () => {
const response = await fetch('https://api.domainku.com/produk', {
// Next.js punya fitur caching terintegrasi
next: { revalidate: 3600 } // Revalidasi setiap 1 jam
});
if (!response.ok) {
throw new Error('Gagal mengambil data produk');
}
return response.json();
});// Komponen utama
export default async function HalamanProduk() {
const daftarProduk = await getDaftarProduk();return (
Daftar Produk Unggulan
{daftarProduk.map(produk => (
))}
);
}Kenapa ini jauh lebih baik?
- Zero Boilerplate State: Kamu tidak perlu lagi
useStateuntuk menyimpan data,setLoading(true), atausetError(error). - Fast Initial Load (SEO Friendly): Data diambil dan di-render di server. Artinya, ketika browser klien menerima respons, HTML-nya sudah lengkap dengan data. Ini super cepat, menghilangkan layout shift yang sering terjadi saat data di-fetch di klien, dan sangat baik untuk SEO.
- Automatic Deduplication: Next.js secara otomatis meng-handle caching dan deduplikasi permintaan
fetchyang sama, bahkan jika dipanggil di beberapa komponen yang berbeda dalam satu render permintaan.
B. Penanganan Error dan Loading yang Elegan
Lantas, bagaimana dengan loading state atau error state? Next.js App Router menyediakan mekanisme bawaan yang jauh lebih clean daripada manual isLoading ?:.
Loading State: Kamu tinggal buat file loading.jsx di segment yang sama. Saat data di komponen sedang di-fetch (sedang pending*), Next.js secara otomatis akan menampilkan UI dari loading.jsx tersebut. Error State: Sama, buat file error.jsx. Jika terjadi error saat fetching data, komponen error ini akan ditampilkan, dan boundary error* ini hanya memengaruhi bagian dari UI yang mengalami masalah, bukan seluruh aplikasi.
Ini adalah pergeseran pola pikir yang wajib kamu adopsi. Data fetching adalah bagian dari rendering, bukan side effect yang harus diurus belakangan.
*
2. Ketika Klien Masih Dibutuhkan: SWR atau React Query
Oke, Server Components menyelesaikan masalah initial load data. Tapi bagaimana jika kita perlu data yang interaktif? Misalnya, infinite scrolling, real-time search, atau data yang sering berubah berdasarkan interaksi pengguna (misalnya, klik tombol refresh).
Untuk skenario ini, kita masih harus menggunakan Client Components ('use client'). Tapi ingat, menggunakan useEffect mentah untuk fetching data di klien tetap merupakan praktik yang kurang efisien di tahun 2024.
Solusinya? Gunakan library khusus data fetching seperti SWR (Stale-While-Revalidate) dari Vercel atau React Query (TanStack Query).
A. Kenapa Harus Pakai SWR/React Query?
Kedua library ini menghilangkan 90% boilerplate useEffect kamu dan menambahkan fitur enterprise yang sangat berguna:
- Caching Otomatis: Mereka menyimpan data yang sudah di-fetch sehingga saat pengguna kembali ke halaman yang sama, data langsung ditampilkan (stale), sementara re-validation (fetching baru) berjalan di background. Ini super cepat.
- Dedupilcating Requests: Jika ada dua komponen yang mencoba mengambil data API yang sama secara bersamaan, library ini hanya akan menjalankan satu permintaan
fetch. - Automatic Refetching: Mereka bisa secara otomatis mengambil data baru saat browser kembali fokus (saat pengguna kembali ke tab browser) atau saat koneksi internet pulih.
- Integrated States: Mereka memberikan status fetching yang jauh lebih rapi (
isLoading,isError,isFetching,isStale).
Contoh SWR (Jauh lebih ringkas dari useEffect):
javascript
// components/DaftarKomentar.jsx
'use client';import useSWR from 'swr';const fetcher = url => fetch(url).then(res => res.json());export default function DaftarKomentar() {
const { data: comments, error, isLoading, mutate } = useSWR('/api/comments', fetcher);if (isLoading) return Memuat komentar...;
if (error) return Gagal memuat: {error.message};// Tombol untuk me-refresh data secara manual
const handleRefresh = () => mutate();Dibandingkan dengan 10-20 baris kode useEffect yang kamu butuhkan untuk mencapai fungsionalitas yang sama (caching, loading, error, cleanup), SWR atau React Query menawarkan kode yang cleaner, lebih mudah di-maintain, dan performa yang jauh lebih superior.
*
3. Menggantikan Axios di Sisi Server: The Power of Server Actions
Selain fetching data (GET requests), masalah besar lainnya adalah mutations (POST, PUT, DELETE requests) atau menangani form submissions. Di masa lalu, ini berarti kita harus membuat endpoint API tersendiri (Route Handler) di Next.js, membuat form di Client Component, dan menggunakan fetch atau Axios untuk memanggil endpoint tersebut.
Next.js kini menyediakan Server Actions. Ini adalah fitur yang memungkinkan kita menjalankan kode server langsung dari interaksi di sisi klien (seperti submit form), tanpa perlu membuat endpoint API terpisah.
A. Kenapa Server Actions Menggantikan API Handler Konvensional?
- Zero API Layer: Kamu tidak perlu membuat Route Handler (file
/api/…) hanya untuk satu fungsi sederhana seperti menyimpan data. Ini mengurangi kompleksitas proyek secara drastis. - Type Safety: Karena Server Action adalah fungsi JavaScript biasa yang dijalankan di server, kamu bisa mendapatkan type safety penuh jika menggunakan TypeScript, karena tidak ada serialisasi HTTP di tengah jalan.
- Automatic Revalidation: Setelah Server Action berhasil dijalankan (misalnya, menambahkan produk baru), kita bisa langsung memanggil
revalidatePath()ataurevalidateTag()untuk memastikan data yang ditampilkan di Server Component lain langsung up-to-date tanpa perlu me-refresh halaman.
Contoh Server Actions untuk submit form:
javascript
// actions/produk.js
'use server'; // Wajib ada di file Server Actionimport { revalidatePath } from 'next/cache';export async function tambahProdukBaru(formData) {
// 1. Ambil data dari FormData
const namaProduk = formData.get('nama');
const harga = formData.get('harga');// 2. Lakukan validasi dan simpan ke database (misal: Prisma)
const produkBaru = await db.produk.create({
data: { nama: namaProduk, harga: parseFloat(harga) },
});// 3. Wajib: Revalidasi cache agar halaman yang menampilkan produk langsung update
revalidatePath('/dashboard/produk');Dan di sisi Client Component, kita panggil fungsi ini langsung:
javascript
// components/FormTambahProduk.jsx
'use client';import { tambahProdukBaru } from '@/actions/produk';// Kita bisa pakai hook useTransition atau useFormState untuk handle loading state
// Tapi secara basic, kita bisa memanggil fungsi ini langsung.
export default function FormTambahProduk() {
// ... menggunakan useFormState
return (
Simpan
);
}Ini adalah masa depan form handling di Next.js: Secure, efisien, dan menghilangkan layer API yang tidak perlu.
*
4. Kesimpulan: Next.js Adalah Game Changer
Era di mana setiap pengambilan data harus melalui siklus useEffect dan useState yang rumit sudah berakhir, terutama untuk initial data fetching.
Next.js dan React Server Components mendorong kita untuk memikirkan data fetching sebagai bagian inheren dari rendering di server, bukan sebagai side effect yang harus ditangani belakangan. Mengadopsi pola ini tidak hanya membuat kode kamu terlihat lebih rapi dan profesional, tetapi juga memberikan dampak performa yang signifikan. Aplikasi menjadi lebih cepat, UX meningkat, dan biaya maintenance kode berkurang.
Penting untuk diingat:
- Initial Fetching (Server Components): Gunakan
async/awaitlangsung. - Interactive Fetching (Client Components): Gunakan dedicated libraries seperti SWR atau React Query.
- Mutations/Forms: Gunakan Server Actions untuk efisiensi dan keamanan.
Jika kamu adalah developer yang ingin membangun aplikasi modern yang cepat, scalable, dan memenuhi standar performa terbaru, atau jika perusahaan kamu membutuhkan partner yang menguasai teknik data fetching Next.js paling mutakhir ini, kami di Javapixa Creative Studio siap membantu. Kami memastikan setiap aplikasi yang kami bangun, mulai dari website hingga sistem aplikasi kompleks, menggunakan arsitektur paling clean dan efisien (RSC, Server Actions, dan SWR), sehingga software yang kamu miliki bukan hanya berfungsi, tetapi juga unggul dalam kecepatan dan developer experience.
Berhenti membuang waktu dengan useEffect yang ribet. Saatnya beralih ke masa depan data fetching yang lebih clean dan cepat bersama Next.js.