Perbedaan useState dan useEffect: Panduan React Hook Dasar

Kalau kamu baru terjun ke dunia React atau lagi transisi dari class component ke function component, pasti sering banget ketemu sama dua hook populer ini: useState dan useEffect.

Hooks adalah fitur di React yang memungkinkan kamu “menyisipkan” fitur-fitur React seperti state dan lifecycle ke dalam functional component. Sebelum ada hooks, fitur-fitur ini cuma bisa dipakai di class component.

Kenapa penting?

  • Functional component lebih simpel, ringan, dan mudah ditulis.
  • Dengan hooks, kamu bisa mengatur state dan efek samping tanpa harus repot-repot bikin class.

Artikel ini cocok banget buat kamu yang masih bingung: "Ini kapan sih pakai useState, dan kapan pakai useEffect?"

Persiapan Proyek

Sebelum kita mulai ngulik komponen di React, tentu kita perlu siapkan dulu proyek React nya, biar bisa langsung praktek dan nggak cuma teori doang.

Syarat Awal

Pastikan kamu udah install Node.js di komputer kamu, minimal versi 14 ya. Buat ngecek, buka terminal atau command prompt terus ketik:

node -v
npm -v

Ini versi yg saya gunakan:

Terminal Windows
Terminal Windows

Kalau keluar versinya berarti udah oke, kalo belum, kamu bisa download Node.js dari situs resmi nodejs.org.

Instalasi React dengan Next.js

Nah, buat mulai proyek React, kita bakal pake Next.js. Next.js ini keren banget karena selain React biasa, dia juga punya fitur kayak routing otomatis dan server-side rendering yang bikin performa aplikasi makin ngebut.

Buka terminal terus ketik perintah ini buat bikin proyek baru:

npx create-next-app@latest bwa-react

Jika ada konfirmasi seperti ini tekan Enter di keyboard

Terminal: Install Next.js
Terminal: Install Next.js
  • √ Would you like to use TypeScript? ... Pilih Yes
  • √ Would you like to use ESLint? ... Pilih Yes
  • √ Would you like to use Tailwind CSS? ... Pilh Yes
  • √ Would you like your code inside a src/ directory? ... Pilih Yes
  • √ Would you like to use App Router? (recommended) ... Pilih Yes
  • √ Would you like to use Turbopack for next dev? ... Pilih Yes
  • √ Would you like to customize the import alias (@/* by default)? ... Pilih No
Terminal: Install Next.js
Terminal: Install Next.js

Jika proses intallasi sudah selesai, masuk ke folder proyeknya:

cd bwa-react

Terus jalankan development server dengan perintah:

npm run dev
Terminal: Menjalankan Next.js
Terminal: Menjalankan Next.js

Biasanya bakal keluar alamat http://localhost:3000 di terminal. Kamu buka alamat itu di browser, dan… voila! Kamu udah punya proyek React dengan Next.js siap pakai.

Tampilan awal Next.js
Tampilan awal Next.js

Kalau kamu pake bun, tinggal ganti aja npm jadi bun di perintah-perintah tadi.


Apa Itu useState?

useState adalah hook buat nyimpen dan mengatur data (state) di dalam komponen. Ibaratnya kayak laci pribadi komponen buat nyimpan data yang bisa berubah.

Bentuk Umum:

const [count, setCount] = useState<number>(0);
  • count: nilai sekarang.
  • setCount: fungsi buat update nilai count.

Contoh Penggunaan:

Counter Sederhana:

'use client';

import { useState } from 'react';

export default function Counter() {
  const [count, setCount] = useState<number>(0);

  return (
    <div>
      <p>Jumlah: {count}</p>
      <button onClick={() => setCount(count + 1)}>Tambah</button>
    </div>
  );
}

Form Input

'use client';

import { useState } from 'react';

export default function InputForm() {
  const [name, setName] = useState<string>('');

  return (
    <input
      value={name}
      onChange={(e) => setName(e.target.value)}
      placeholder="Nama kamu"
    />
  );
}

Kapan pakai useState?

Kalau kamu pengen nyimpan data yang:

  • Bisa berubah (dinamis)
  • Dibutuhkan saat render ulang

Apa Itu useEffect?

useEffect adalah hook buat ngejalanin efek samping (side effects). Maksudnya, hal-hal yang nggak langsung berhubungan sama proses render React, kayak:

  • Ambil data dari API
  • Manipulasi document.title
  • Simpan data ke localStorage
  • Timer/interval
  • Event listener

Bentuk Umum:

useEffect(() => {
  // efek samping di sini
}, [dependency]);

Jenis-jenis Dependensi:

DependensiKapan Jalan
Kosong []Cuma sekali, setelah komponen pertama kali muncul (mount)
Tidak adaTiap kali render
Ada nilai [x]Jalan kalau x berubah

Contoh: Ubah Title Tab

'use client';

import { useEffect, useState } from 'react';

export default function TitleChanger() {
  const [count, setCount] = useState<number>(0);

  useEffect(() => {
    document.title = `Klik: ${count}`;
  }, [count]);

  return <button onClick={() => setCount(count + 1)}>Klik aku!</button>;
}

Kapan Pakai useState vs useEffect?

SituasiPakai Hook Apa?Penjelasan
Nyimpen nilai input formuseStateKarena kita butuh update data saat user ketik
Fetch data dari APIuseEffectIni termasuk efek samping
Hitung jumlah klik tomboluseStateKarena data klik disimpan di state
Update judul tab browseruseEffectKarena manipulasi DOM dilakukan di luar React
Simpan data ke localStorage saat state berubahuseState + useEffectGunakan state buat nyimpen, efek untuk nyimpan ke localStorage

Contoh Praktis: Simpan Nama ke localStorage

Studi Kasus

Kita mau:

  • Ambil nama dari localStorage pas komponen pertama kali muncul.
  • Update localStorage setiap kali nama berubah.

Kode Lengkap:

Buat file pada direktori src/components/InputName.tsx

// src/components/InputName.tsx
"use client";

import { useState, useEffect } from "react";

export default function UserForm() {
  const [name, setName] = useState<string>("");

  // Ambil nama dari localStorage saat pertama render
  useEffect(() => {
    const savedName = localStorage.getItem("username");
    if (savedName) {
      setName(savedName);
    }
  }, []);

  // Simpan ke localStorage setiap kali 'name' berubah
  useEffect(() => {
    localStorage.setItem("username", name);
  }, [name]);

  // Fungsi untuk menghapus nama dari localStorage dan state
  const handleDelete = () => {
    localStorage.removeItem("username");
    setName("");
  };

  return (
    <div className="flex flex-col w-3xs space-y-4">
      <input
        type="text"
        value={name}
        onChange={(e) => setName(e.target.value)}
        placeholder="Masukkan nama kamu"
        className="border px-4 py-2 rounded w-full"
      />
      <button
        onClick={handleDelete}
        disabled={!name}
        className="ml-auto bg-red-500 text-white px-4 py-2 rounded hover:bg-red-600 transition-all duration-300 disabled:opacity-50"
      >
        Hapus Nama
      </button>
    </div>
  );
}

📌 Penjelasan:

  • Saat pertama kali render, kita cek localStorage.
  • Setelah user ngetik dan name berubah, kita simpan ulang ke localStorage.
  • handleDelete() akan:
    • Menghapus data dari localStorage dengan removeItem('username').
    • Reset state name ke string kosong.
  • Efek: input akan langsung kosong, dan tidak disimpan lagi ke localStorage sampai pengguna mengetik ulang.

Buka page.tsx lalu ubah kode jadi seperti berikut:

// scr/app/page.tsx
import InputName from "@/components/InputName";

export default function Home() {
  return (
    <div className="grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20 font-[family-name:var(--font-geist-sans)]">
      <main className="flex flex-col gap-[32px] row-start-2 items-center sm:items-start">
        <InputName />
      </main>
    </div>
  );
}

Hasilnya:

Contoh kombinasi useEffect dan useState

Kesalahan Umum yang Sering Dilakukan

Belajar React Hooks itu seru, tapi banyak juga jebakan Batman-nya. Nah, biar kamu nggak jatuh ke lubang yang sama, ini dia beberapa kesalahan umum yang sering banget terjadi pas pakai useState dan useEffect:

Lupa Menambahkan Dependency di useEffect

Contoh salah:

useEffect(() => {
  console.log(name);
}, []); // name seharusnya masuk ke dependency

Penjelasan:

Kalau name nggak dimasukin ke dependency array, useEffect nggak bakal ngejalanin ulang efeknya meskipun name berubah. Ini bisa bikin bug yang susah dilacak.

Solusi:

useEffect(() => {
  console.log(name);
}, [name]);

Bikin Infinite Loop Tanpa Sadar

Contoh salah:

const [count, setCount] = useState(0);

useEffect(() => {
  setCount(count + 1); // ini bakal terus-menerus nge-trigger re-render
}, [count]);

Penjelasan:

Karena setCount di-trigger tiap kali count berubah, efek ini akan terus jalan, bikin infinite loop dan nge-crash aplikasi.

Solusi:

Hindari update state di dalam useEffect yang bergantung pada state itu sendiri, kecuali kamu tahu persis apa yang kamu lakukan (misalnya pakai kondisi).

Naruh Logika Berat di useState

const [result, setResult] = useState(() => {
  // ini dieksekusi setiap render
  return hitungLamaBanget();
});

Solusi:

Kalau hitungannya berat, kamu bisa manfaatkan fungsi inisialisasi useState:

const [result, setResult] = useState(() => hitungLamaBanget()); // cuma dieksekusi sekali

Efek Samping Tanpa Cleanup

Misalnya pakai timer atau event listener tapi nggak dibersihin.

Contoh salah:

useEffect(() => {
  window.addEventListener('resize', handleResize);
}, []);

Solusi:

useEffect(() => {
  window.addEventListener('resize', handleResize);

  return () => {
    window.removeEventListener('resize', handleResize);
  };
}, []);

Terlalu Banyak useEffect yang Redundant

Kadang kita bisa gabungkan beberapa useEffect jadi satu daripada bikin 3 efek berbeda yang sebenarnya bisa dikelola bareng.

Tips:

Kelola efek yang berkaitan di satu useEffect, supaya lebih rapi dan terkontrol.

Tips dan Best Practice

  • ❌ Jangan pakai useEffect buat logika render biasa (misal if, map, dll).
  • 🔄 Hindari infinite loop: pastikan dependensinya benar.
  • 🧹 Pakai cleanup kalau ada efek yang harus dibersihkan (interval, event listener).

Contoh Cleanup:

useEffect(() => {
  const interval = setInterval(() => {
    console.log('Running...');
  }, 1000);

  return () => {
    clearInterval(interval);
  };
}, []);

Kesimpulan

  • 🧠 useState: Buat nyimpen dan update data lokal di komponen.
  • useEffect: Buat efek samping di luar React seperti API, localStorage, DOM.
  • Kombinasikan keduanya buat bikin komponen interaktif dan dinamis.

Kalau komponenmu butuh “ingat sesuatu” dan “ngelakuin sesuatu di luar React”, maka useState dan useEffect adalah senjata wajib kamu.

📚 Artikel Terkait

Biar makin mantap belajar React, kamu bisa lanjut baca artikel-artikel berikut:

  1. Mengenal Komponen di React JS: Functional vs Class Pelajari perbedaan antara komponen class dan functional, serta kenapa sekarang banyak developer lebih memilih functional component + hooks!
  2. Cara Deploy Website Statis ke Vercel Lewat GitHub (Lengkap + Contoh) Setelah paham useState dan useEffect, saatnya publish proyek kamu ke internet. Artikel ini panduannya step-by-step!

🎓 Rekomendasi Kelas Gratis

Mau langsung praktik dan bikin project beneran? Coba kelas gratis dari BuildWithAngga berikut:

🔗 Membuat Website Voucher Game dengan Terintegrasi API VocaGame

Di kelas ini kamu bakal belajar cara ambil data dari API, pakai React Hooks (yes, termasuk useState dan useEffect!), dan bikin tampilan interaktif. Cocok banget buat pemula!