Jangan Lagi Fetch Data di Next.js Pakai `useEffect` Kamu Harus Coba Metode Ini
Gimana kabar ngoding-nya, guys? Kalau kamu lagi asyik banget develop aplikasi pakai Next.js, entah itu versi 13 atau 14 dengan App Router yang bikin pusing di awal tapi powerful banget, ada satu kebiasaan lama yang wajib banget kita tinggalkan: fetching data pakai hook useEffect.
Aku tahu, useEffect itu seperti sahabat lama di React. Dulu, hampir semua side effect kita tumpahkan di sana, termasuk mengambil data dari API. Tapi, di ekosistem Next.js modern, khususnya yang mengutamakan performa, Server Components, dan render secepat kilat, menggunakan useEffect untuk data fetching adalah bottleneck yang bikin aplikasi kita jadi lambat dan ribet diatur.
Intinya, Next.js diciptakan untuk membuat aplikasi secepat mungkin, dan cara tercepat untuk mendapatkan data adalah di sisi server, sebelum browser sempat berpikir. Kalau kamu masih pakai useEffect, artinya kamu memaksa aplikasi kamu jadi Client-Side Rendering (CSR) murni, yang mana menghilangkan semua keunggulan utama Next.js.
Yuk, kita bongkar kenapa metode lama ini harus pensiun, dan apa saja senjata modern yang bisa kamu pakai untuk data fetching yang cepat, efisien, dan developer-friendly.
*
Kenapa useEffect Jadi Villain di Next.js Modern?
Next.js, terutama setelah adopsi App Router, menggeser paradigma dari client-centric ke server-centric. Tujuannya jelas: faster time-to-interact (TTI) dan better SEO.
Ketika kamu pakai useEffect untuk fetching:
- Rendering Pertama (Server Side): Next.js merender komponen kamu di server (atau pre-render).
- HTML Dikirim: HTML dikirim ke browser, tapi isinya belum ada data (atau data loading state).
- Hydration (Client Side): Browser menerima HTML dan mulai me-render ulang (proses hydration).
useEffectJalan: BarulahuseEffectdipanggil, fetch data dari API.- State Update: Data masuk, komponen re-render.
Lihat kan? Ada jeda yang lumayan panjang. Ini menciptakan waterfall masalah: loading spinners yang muncul lama, Cumulative Layout Shift (CLS) yang buruk, dan SEO yang kurang optimal karena konten utama tidak ada di initial load.
Nah, Next.js sudah menyediakan solusi yang jauh lebih elegan. Jadi, mari kita move on ke method yang lebih powerful.
*
1. The New Standard: Fetching di Server Components
Ini adalah cara fetching data paling ideal di Next.js App Router (Next.js 13 ke atas). Next.js telah mengintegrasikan fitur native fetch API dengan sangat baik.
Ingat, secara default, semua komponen di App Router adalah Server Components (SC). SC ini punya kekuatan untuk mengakses database atau fetch data API eksternal secara langsung, sebelum HTML dikirim ke browser.
Mekanisme Paling Simple dan Cepat
Di Server Component, kamu bisa langsung menggunakan fungsi await fetch() di luar hook atau lifecycle apapun:
javascript
// app/page.jsx (Ini otomatis Server Component)
async function getPosts() {
const res = await fetch('https://api.domain.com/posts', {
// Tambahkan caching strategy
next: { revalidate: 3600 } // Revalidate setelah 1 jam
});if (!res.ok) {
// Ini penting: kalau gagal, lempar error
throw new Error('Failed to fetch data');
}return res.json();
}export default async function HomePage() {
const posts = await getPosts(); // Tunggu data selesai sebelum renderreturn (
Selamat Datang di Website Javapixa
{posts.map(post => (
{post.title}
{post.content}
))}
);
}Kenapa ini bagus banget?
- Zero Overhead Client: Tidak ada bundle size JavaScript tambahan di sisi client untuk fetching. Semua terjadi di server.
- SEO Optimal: Saat initial render, data sudah ada di dalam HTML yang dikirim ke browser dan search engine crawler.
- Automatic Caching: Next.js secara cerdas akan menduplikasi fetch requests yang sama dan menyediakan built-in memoization dan deduplication. Kamu tinggal tentukan strategi caching menggunakan objek
next.
Penting: Kalau kamu ingin membuat form atau tombol interaktif yang mengubah data, kamu harus menggunakan Client Component ('use client';) dan mengombinasikannya dengan Server Actions (metode modern untuk mutasi data) atau metode client-side lain (seperti SWR/React Query yang akan kita bahas).*
2. Metode Warisan yang Masih Relevan (Pages Router & App Router Shared)
Kalau kamu masih menggunakan Next.js versi lama (Pages Router) atau di App Router kamu perlu menentukan kapan data di-fetch (misalnya pre-render statik), metode ini masih wajib kamu tahu.
A. getStaticProps (Static Site Generation - SSG)
Digunakan untuk halaman yang jarang berubah dan performa harus maksimal. Next.js akan mengambil data saat build time (atau saat revalidation). Hasilnya adalah HTML statis murni yang sangat cepat.
javascript
// Pages Router
export async function getStaticProps() {
const res = await fetch('https://api.domain.com/static-data');
const data = await res.json();B. getServerSideProps (Server Side Rendering - SSR)
Digunakan untuk halaman yang sangat dinamis, di mana data harus selalu fresh pada setiap request (misalnya, dashboard pengguna yang sensitif terhadap waktu).
javascript
// Pages Router
export async function getServerSideProps(context) {
const res = await fetch('https://api.domain.com/dynamic-data');
const data = await res.json();Meskipun di App Router kedua fungsi ini digantikan oleh fungsi fetch yang ada di Server Component, memahami konsep SSG dan SSR adalah kunci untuk menentukan strategi caching di App Router.
*
3. Client-Side Heroes: SWR dan React Query
Oke, kita sudah bahas metode server-side yang ideal. Tapi, bagaimana jika kita memang terpaksa harus fetch data di sisi client?
Kapan kita terpaksa menggunakan Client-Side Fetching?
- Data yang memerlukan interaksi pengguna (misalnya, filter data, infinite scrolling).
- Data yang benar-benar sensitif terhadap user-specific state yang hanya bisa diakses di browser (misalnya, token dari local storage).
- Mutasi data (POST, PUT, DELETE) setelah form disubmit.
Di sinilah kita harus meninggalkan useEffect dan beralih ke data fetching libraries yang memang didesain untuk managing remote state.
3.1 SWR (Stale-While-Revalidate)
SWR adalah library kecil buatan Vercel (tim di balik Next.js) yang fokus pada kecepatan, caching, dan real-time experience. Nama SWR sendiri adalah strategi caching HTTP yang berarti: tunjukkan data lama (stale), revalidate (ambil data baru) di latar belakang, lalu update jika ada perubahan.
Keunggulan SWR:
- Global Cache: Semua data API kamu dikelola secara terpusat.
Automatic Refetching: Otomatis refetch saat jendela browser kembali fokus, saat koneksi online* lagi, atau saat interval tertentu. Deduping: Jika ada dua komponen berbeda yang mencoba fetch API yang sama, SWR hanya akan menjalankan satu request* saja.
Contoh penggunaan SWR:
javascript
'use client'; // Harus Client Componentimport useSWR from 'swr';const fetcher = url => fetch(url).then(res => res.json());function Profile() {
const { data, error, isLoading } = useSWR('/api/user/profile', fetcher);if (error) return Gagal mengambil data user.;
if (isLoading) return Loading...;return Halo, {data.name}!;
}Dengan SWR, kita tidak perlu lagi pusing memikirkan state isLoading, error, atau setData. Semua sudah diurus oleh hook useSWR, membuat code kita jauh lebih bersih daripada menggunakan useState dan useEffect secara manual.
3.2 React Query (TanStack Query)
Jika SWR adalah solusi cepat dan minimalis, maka React Query adalah solusi all-in-one yang sangat kuat, ideal untuk aplikasi yang kompleks dengan banyak interaksi data.
React Query (sekarang TanStack Query) pada dasarnya adalah sistem manajemen state untuk data server kamu.
Keunggulan React Query:
Strong Caching Control: Kontrol sangat detail terhadap cache (misalnya, data dianggap fresh* berapa lama).
- Automatic Retry & Window Focus Refetching: Sama seperti SWR, tapi dengan opsi konfigurasi yang lebih mendalam.
Devtools: Tools developer yang luar biasa untuk memantau status semua query dan cache* kamu. Optimistic Updates: Memungkinkan kamu menampilkan data seolah-olah mutasi berhasil (sebelum server* benar-benar merespons), memberikan UX yang sangat cepat.
Contoh penggunaan React Query:
javascript
'use client';import { useQuery } from '@tanstack/react-query';const fetchTodos = async () => {
const res = await fetch('/api/todos');
if (!res.ok) throw new Error('Failed to fetch todos');
return res.json();
};function TodoList() {
// Key 'todos' digunakan untuk mengidentifikasi dan me-manage cache
const { data: todos, isLoading, isError } = useQuery({
queryKey: ['todos'],
queryFn: fetchTodos
});if (isLoading) return Mengambil list tugas...;
if (isError) return Terjadi kesalahan.;return (
{todos.map(todo => {todo.title})}
);
}Untuk aplikasi skala besar di Next.js, React Query seringkali menjadi pilihan utama karena fitur mutasi dan manajemen cache yang sangat komprehensif.
*
Jangan Lupakan Data Mutasi: Server Actions
Next.js App Router memperkenalkan solusi yang paling efisien untuk mengirim data dari client ke server (mutasi): Server Actions.
Server Actions memungkinkan kamu memanggil fungsi server secara langsung dari event handler di Client Component, tanpa perlu membuat endpoint API secara manual.
Ini adalah solusi terbaik untuk menggantikan POST request yang biasanya kamu lakukan menggunakan useEffect dan fetch biasa.
javascript
// server-actions.js
'use server'; // Ini WAJIB adaexport async function createPost(formData) {
// Lakukan validasi dan operasi database di sini (di sisi server)
const title = formData.get('title');
// ... simpan ke database
console.log(Post baru dibuat: ${title});Dan di sisi client kamu tinggal panggil aksinya:
javascript
// PostForm.jsx ('use client' jika perlu interaksi state)
import { createPost } from './server-actions';export default function PostForm() {
return (
{/ Langsung panggil Server Action /}
Submit Post
);
}Menggunakan Server Actions menghilangkan kebutuhan akan banyak hook useEffect untuk menangani submission form dan state yang berkaitan dengan mutasi data.
*
Kesimpulan: Upgrade Skill, Upgrade Aplikasi
Next.js terus berkembang dengan sangat cepat. Filosofi intinya adalah membuat developer lebih fokus pada konten dan bisnis logik, sementara Next.js mengurus performa dan pengiriman data seefisien mungkin.
Jika kamu masih menggunakan useEffect untuk fetching data di Next.js, kamu sedang melawan arus dan mengorbankan performa aplikasi.
Pilihan Terbaik Kamu di Next.js Modern:
- Default: Gunakan native
fetchdi Server Components. - Highly Interactive/Mutasi: Gunakan SWR atau React Query (di Client Components) yang dikombinasikan dengan Server Actions.
Transisi ke metode fetching modern ini memang terasa seperti kurva belajar baru, tapi hasilnya sebanding: aplikasi yang lebih cepat, kode yang lebih bersih, dan maintenance yang jauh lebih mudah.
Di Javapixa Creative Studio, kami selalu berkomitmen menggunakan praktik terbaik dan teknologi terkini—khususnya Next.js dan App Router—untuk memastikan setiap website dan aplikasi yang kami bangun tidak hanya terlihat keren, tetapi juga memiliki performa yang maksimal dan struktur kode yang maintainable. Jika tim kamu membutuhkan expert untuk migrasi arsitektur Next.js atau membangun aplikasi performa tinggi dari nol, hubungi kami. Kami siap membantu project kamu berjalan secepat kilat!
Yuk, stop pakai useEffect hari ini, dan rasakan sendiri perbedaan kecepatan aplikasi kamu! Selamat ngoding dan semoga performa aplikasi kamu selalu hijau di Lighthouse!