Halo teman-teman semuanya, setelah sebelumnya kita belajar bagaimana melakukan edit dan update data ke API menggunakan kombinasi useQuery
dan useMutation
, di tutorial kali ini kita akan lanjut belajar bagaimana cara melakukan hapus data atau delete ke API menggunakan TanStack Query. Teknik yang akan kita gunakan kali ini yaitu:
useMutation
untuk menjalankan proses hapus data.
queryClient.invalidateQueries()
untuk me-refresh data setelah berhasil dihapus.
Langkah 1 - Delete Data Dengan useMutation
dan invalidateQueries
Langsung saja, silahkan teman-teman buka file src/views/products/index.jsx
, kemudian ubah semua kode-nya menjadi seperti berikut ini.
src/views/products/index.jsx
//import hook useQuery dan useMutation
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
//import Link
import { Link } from 'react-router';
//import service Api
import Api from '../../api';
const ProductIndex = () => {
// Initialize QueryClient
const queryClient = useQueryClient();
// Fetch data from API using react-query
const { data, isLoading, isError, error } = useQuery({
// Set the query key
queryKey: ['products'],
// Set the query function
queryFn: async () => {
const res = await Api.get('/api/products');
return res.data.data.data;
}
});
// Mutation for deleting product
const deleteProduct = useMutation({
mutationFn: async (id) => {
await Api.delete(`/api/products/${id}`);
},
onSuccess: () => {
// Refresh the product list after deletion
queryClient.invalidateQueries({ queryKey: ['products'] });
},
});
// Handle Delete Button Click
const handleDelete = (id) => {
if (confirm("Are you sure you want to delete this product?")) {
// Call the delete mutation
deleteProduct.mutate(id);
}
};
return (
<div className="container mt-5 mb-5">
<div className="row">
<div className="col-md-12">
<Link
to="/products/create"
className="btn btn-md btn-success rounded-5 shadow border-0 mb-3"
>
ADD NEW PRODUCT
</Link>
<div className="card border-0 rounded-3 shadow">
<div className="card-body">
{/* Loading State */}
{isLoading && (
<div className="alert alert-info text-center">Loading...</div>
)}
{/* Error State */}
{isError && (
<div className="alert alert-danger text-center">
Error: {error.message}
</div>
)}
{/* Tabel Produk */}
{!isLoading && !isError && (
<table className="table table-bordered">
<thead className="bg-dark text-white">
<tr>
<th scope="col">Image</th>
<th scope="col">Title</th>
<th scope="col">Description</th>
<th scope="col">Price</th>
<th scope="col">Stock</th>
<th scope="col" style={{ width: "15%" }}>Actions</th>
</tr>
</thead>
<tbody>
{data.length > 0 ? (
data.map((product) => (
<tr key={product.id}>
<td className="text-center">
<img
src={product.image}
alt={product.title}
width="200"
className="rounded-3"
/>
</td>
<td>{product.title}</td>
<td>{product.description}</td>
<td>{product.price?.toLocaleString("id-ID")}</td>
<td>{product.stock}</td>
<td className="text-center">
<Link
to={`/products/edit/${product.id}`}
className="btn btn-sm btn-primary rounded-5 shadow border-0 me-2"
>
EDIT
</Link>
<button
onClick={() => handleDelete(product.id)}
className="btn btn-sm btn-danger rounded-5 shadow border-0"
disabled={deleteProduct.isPending}
>
{deleteProduct.isPending ? "..." : "DELETE"}
</button>
</td>
</tr>
))
) : (
<tr>
<td colSpan={6} className="text-center">
<div className="alert alert-danger mb-0">
No data available
</div>
</td>
</tr>
)}
</tbody>
</table>
)}
</div>
</div>
</div>
</div>
</div>
);
};
export default ProductIndex;
Dari perubahan kode di atas, pertama kita import useQueryClient
dari TanStack Query.
//import hook useQuery dan useMutation
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
Kemudian kita lakukan inisialisasi queryClient
.
// Initialize QueryClient
const queryClient = useQueryClient();
Selanjutnya, kita membuat mutation dengan nama deleteProduct
.
// Mutation for deleting product
const deleteProduct = useMutation({
//...
});
Di dalamnya, untuk mutationFn
kita memanggil REST API untuk proses delete data, yaitu endpoint /api/products/:id
dan method yang digunakan adalah DELETE
.
mutationFn: async (id) => {
await Api.delete(`/api/products/${id}`);
},
Jika berhasil, maka kita akan lakukan invalidateQuery
ke sebuah queryKey
yang bernama products
. Sehingga list data products-nya akan diperbarui.
onSuccess: () => {
// Refresh the product list after deletion
queryClient.invalidateQueries({ queryKey: ['products'] });
},
Selanjutnya, kita membuat function yang bernama handleDelete
. Fungsi ini akan dijalankan ketika button DELETE
diklik.
<button
onClick={() => handleDelete(product.id)}
className="btn btn-sm btn-danger rounded-5 shadow border-0"
disabled={deleteProduct.isPending}
>
{deleteProduct.isPending ? "..." : "DELETE"}
</button>
const handleDelete = (id) => {
//...
}
Di dalamnya, kita membuat sebuah konfirmasi, jika bernailai true
, maka kita akanmemanggil mutation yang bernama deleteProduct
dan mengirimkan id
.
// Call the delete mutation
deleteProduct.mutate(id);
Langkah 2 - Uji Coba Delete Data
Sekarang silahkan teman-teman coba klik button DELETE
di salah satu data yang dimiliki, jika berhasil maka kurang lebih seperti berikut ini.

Silahkan klik OK
, maka data product berhasil dihapus.

Kesimpulan
Pada tutorial ini, kita telah belajar cara menghapus data ke API menggunakan useMutation
dan melakukan invalidasi query menggunakan queryClient.invalidateQueries()
agar data otomatis di-refresh.
Jika teman-teman ada kendala saat belajar, jangan sungkan-sungkan untuk bertanya melalui kolom komentar atau group Telegram milik SantriKoding.
Terima Kasih