Membuat CRUD React dengan API Laravel: Tambah, Edit, Hapus (Part 3)

⚛️ Seri Fullstack React + Laravel — Manajemen Produk

  1. Part 1: Backend — REST API Laravel
  2. Part 2: Setup React & Tampil Data
  3. Part 3: CRUD React ↔ API (sedang dibaca)
  4. Part 4: Pencarian & Autentikasi Sanctum

Di Part 2, React kita sudah bisa menampilkan data produk dari API Laravel. Sekarang di Part 3 kita buat aplikasi ini benar-benar interaktif dengan CRUD: menambah, mengedit, dan menghapus produk — semuanya langsung berkomunikasi dengan API Laravel.

Alur CRUD React ke API
Alur CRUD React ke API

Konsep CRUD di React

Kunci CRUD di React adalah state. Ketika kita menambah atau menghapus produk lewat API, kita juga memperbarui state produk di React. Karena React otomatis merender ulang saat state berubah, tampilan langsung ikut berubah tanpa perlu me-refresh halaman — inilah keunggulan aplikasi React.

Kita akan memakai instance axios (api) yang dibuat di Part 2, dengan base URL http://localhost:8000/api.

Membuat Form dengan Controlled Component

Di React, input form dikendalikan oleh state — disebut controlled component. Buat src/FormProduk.jsx:

import { useState } from 'react';
import api from './api';

function FormProduk({ onSimpan }) {
  const [form, setForm] = useState({ nama: '', kategori: '', harga: '', stok: '' });

  const handleChange = (e) => {
    setForm({ ...form, [e.target.name]: e.target.value });
  };

  const handleSubmit = (e) => {
    e.preventDefault();

    api.post('/produk', form)
      .then((res) => {
        onSimpan(res.data.data);
        setForm({ nama: '', kategori: '', harga: '', stok: '' });
      })
      .catch((err) => console.error('Gagal menyimpan:', err));
  };

  return (
    <form onSubmit={handleSubmit}>
      <input name="nama" value={form.nama} onChange={handleChange} placeholder="Nama produk" />
      <input name="kategori" value={form.kategori} onChange={handleChange} placeholder="Kategori" />
      <input name="harga" value={form.harga} onChange={handleChange} placeholder="Harga" type="number" />
      <input name="stok" value={form.stok} onChange={handleChange} placeholder="Stok" type="number" />
      <button type="submit">Simpan</button>
    </form>
  );
}

export default FormProduk;

Perhatikan pola handleChange: { ...form, [e.target.name]: e.target.value } menyalin seluruh nilai form lama, lalu menimpa satu field yang berubah. Berkat atribut name pada tiap input, satu fungsi bisa menangani semua field sekaligus.

Form tambah produk di React
Form tambah produk di React

Mengelola State di Komponen Induk

Agar form dan tabel saling terhubung, kita pindahkan state produk ke App.jsx sebagai induk. Ketika form menyimpan produk baru, ia memberi tahu induk lewat callback:

import { useState, useEffect } from 'react';
import api from './api';
import FormProduk from './FormProduk';

function App() {
  const [produk, setProduk] = useState([]);

  useEffect(() => {
    api.get('/produk').then((res) => setProduk(res.data.data));
  }, []);

  // dipanggil saat produk baru ditambahkan
  const tambahProduk = (baru) => {
    setProduk([baru, ...produk]);
  };

  // hapus produk
  const hapusProduk = (id) => {
    if (!confirm('Yakin hapus produk ini?')) return;

    api.delete(`/produk/${id}`)
      .then(() => setProduk(produk.filter((p) => p.id !== id)))
      .catch((err) => console.error(err));
  };

  return (
    <div className="container">
      <h1>Manajemen Produk</h1>

      <FormProduk onSimpan={tambahProduk} />

      <table border="1" cellPadding="8">
        <thead>
          <tr>
            <th>Nama</th><th>Kategori</th><th>Harga</th><th>Stok</th><th>Aksi</th>
          </tr>
        </thead>
        <tbody>
          {produk.map((p) => (
            <tr key={p.id}>
              <td>{p.nama}</td>
              <td>{p.kategori}</td>
              <td>Rp {p.harga.toLocaleString('id-ID')}</td>
              <td>{p.stok}</td>
              <td>
                <button onClick={() => hapusProduk(p.id)}>Hapus</button>
              </td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

export default App;

Cara Kerja Tambah dan Hapus

  • Tambah: form mengirim api.post('/produk', form). Setelah API merespons dengan data produk baru, callback tambahProduk menambahkannya ke depan array state — tabel langsung memperlihatkannya.
  • Hapus: api.delete(...) mengirim permintaan ke API, lalu setProduk(produk.filter(...)) membuang produk itu dari state — baris langsung hilang dari tabel tanpa reload.
Daftar produk setelah tambah data
Daftar produk setelah tambah data

Menambahkan Fitur Edit

Untuk edit, kita simpan produk yang sedang diedit di state, lalu kirim PUT. Berikut inti logikanya (bisa Anda kembangkan ke dalam form terpisah):

const [sedangEdit, setSedangEdit] = useState(null);

const updateProduk = (id, data) => {
  api.put(`/produk/${id}`, data)
    .then((res) => {
      setProduk(produk.map((p) => (p.id === id ? res.data.data : p)));
      setSedangEdit(null);
    })
    .catch((err) => console.error(err));
};

Pola produk.map((p) => (p.id === id ? dataBaru : p)) menggantikan satu produk yang diubah, sambil mempertahankan yang lain — cara umum memperbarui satu item dalam array state React.

Menampilkan Notifikasi Sederhana

Anda bisa menambahkan state pesan untuk memberi tahu pengguna:

const [pesan, setPesan] = useState('');

// setelah berhasil menyimpan
setPesan('Produk berhasil ditambahkan.');
setTimeout(() => setPesan(''), 3000);

Lalu tampilkan {pesan && <div className="alert">{pesan}</div>} di atas form. Notifikasi akan hilang otomatis setelah 3 detik.

Penutup

Aplikasi produk Anda kini benar-benar fullstack dan interaktif — React mengirim perubahan ke API Laravel, dan tampilan diperbarui secara instan lewat state, tanpa reload halaman. Anda telah menguasai inti CRUD di React: controlled component, mengirim data dengan axios, dan mengelola state array.

Di Part 4 pamungkas, kita tambahkan pencarian, filter, serta autentikasi dengan Laravel Sanctum agar API hanya bisa diakses pengguna yang login. Sampai jumpa!

Referensi: untuk pendalaman lebih lanjut, kunjungi dokumentasi resmi React dan Laravel.

Baca Juga

Ali Akbar

Software Developer yang fokus mengembangkan aplikasi berbasis Web dan Desktop. Senang mempelajari teknologi baru terutama di bidang web design dan web development.

View all posts by Ali Akbar →

Tinggalkan Balasan

Alamat email Anda tidak akan dipublikasikan. Ruas yang wajib ditandai *