Tutorial React.js untuk Mengelola Produk dengan API REST

Dalam tutorial ini, kita akan membuat aplikasi React.js sederhana yang dapat melakukan operasi CRUD (Create, Read, Update, Delete) pada data produk menggunakan API REST yang telah disediakan. Berikut adalah langkah-langkahnya:

Prasyarat

Sebelum memulai, pastikan Anda telah menginstal:

Langkah 1: Membuat Proyek React

  1. Buka terminal dan jalankan perintah berikut untuk membuat proyek React baru menggunakan Create React App:

    npx create-react-app react-products-app
    cd react-products-app
  2. Jalankan aplikasi untuk memastikan semuanya berjalan dengan baik:

    npm start

    Aplikasi akan berjalan di http://localhost:3000/.

Langkah 2: Menginstal Dependensi Tambahan

Kita akan menggunakan axios untuk melakukan panggilan API dan react-router-dom untuk routing.

npm install axios react-router-dom

Langkah 3: Menyiapkan Struktur Proyek

Buat struktur folder berikut di dalam folder src:

src/

├── components/
│   ├── ProductList.js
│   ├── ProductDetail.js
│   ├── CreateProduct.js
│   ├── UpdateProduct.js
│   └── Navbar.js

├── App.js
├── index.js
└── ... (file lainnya)

Langkah 4: Membuat Komponen Navigasi

Buat komponen Navbar untuk navigasi antar halaman.

// src/components/Navbar.js
import React from 'react';
import { Link } from 'react-router-dom';

const Navbar = () => {
    return (
        <nav>
            <ul>
                <li><Link to="/">Produk</Link></li>
                <li><Link to="/create">Tambah Produk</Link></li>
            </ul>
        </nav>
    );
};

export default Navbar;

Langkah 5: Mengonfigurasi Routing

Atur routing di App.js menggunakan react-router-dom.

// src/App.js
import React from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import Navbar from './components/Navbar';
import ProductList from './components/ProductList';
import ProductDetail from './components/ProductDetail';
import CreateProduct from './components/CreateProduct';
import UpdateProduct from './components/UpdateProduct';

const App = () => {
    return (
        <Router>
            <Navbar />
            <div className="container">
                <Routes>
                    <Route path="/" element={<ProductList />} />
                    <Route path="/products/:id" element={<ProductDetail />} />
                    <Route path="/create" element={<CreateProduct />} />
                    <Route path="/update/:id" element={<UpdateProduct />} />
                </Routes>
            </div>
        </Router>
    );
};

export default App;

Langkah 6: Membuat Komponen ProductList

Komponen ini akan menampilkan semua produk.

// src/components/ProductList.js
import React, { useEffect, useState } from 'react';
import axios from 'axios';
import { Link } from 'react-router-dom';

const ProductList = () => {
    const [products, setProducts] = useState([]);
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState(null);

    useEffect(() => {
        axios.get('http://localhost:3000/api/products')
            .then(response => {
                setProducts(response.data);
                setLoading(false);
            })
            .catch(error => {
                setError('Gagal memuat data');
                setLoading(false);
            });
    }, []);

    const handleDelete = (id) => {
        if (window.confirm('Apakah Anda yakin ingin menghapus produk ini?')) {
            axios.delete(`http://localhost:3000/api/products/${id}`)
                .then(() => {
                    setProducts(products.filter(product => product.id !== id));
                })
                .catch(() => {
                    alert('Gagal menghapus produk');
                });
        }
    };

    if (loading) return <p>Loading...</p>;
    if (error) return <p>{error}</p>;

    return (
        <div>
            <h2>Daftar Produk</h2>
            <table border="1" cellPadding="10">
                <thead>
                    <tr>
                        <th>ID</th>
                        <th>Nama</th>
                        <th>Harga</th>
                        <th>Stok</th>
                        <th>Aksi</th>
                    </tr>
                </thead>
                <tbody>
                    {products.map(product => (
                        <tr key={product.id}>
                            <td>{product.id}</td>
                            <td>
                                <Link to={`/products/${product.id}`}>{product.name}</Link>
                            </td>
                            <td>${product.price}</td>
                            <td>{product.stock}</td>
                            <td>
                                <Link to={`/update/${product.id}`}>Edit</Link> | 
                                <button onClick={() => handleDelete(product.id)} style={{ marginLeft: '10px' }}>
                                    Delete
                                </button>
                            </td>
                        </tr>
                    ))}
                </tbody>
            </table>
        </div>
    );
};

export default ProductList;

Langkah 7: Membuat Komponen ProductDetail

Komponen ini akan menampilkan detail satu produk.

// src/components/ProductDetail.js
import React, { useEffect, useState } from 'react';
import axios from 'axios';
import { useParams, Link } from 'react-router-dom';

const ProductDetail = () => {
    const { id } = useParams();
    const [product, setProduct] = useState(null);
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState(null);

    useEffect(() => {
        axios.get(`http://localhost:3000/api/products/${id}`)
            .then(response => {
                setProduct(response.data);
                setLoading(false);
            })
            .catch(error => {
                setError('Produk tidak ditemukan');
                setLoading(false);
            });
    }, [id]);

    if (loading) return <p>Loading...</p>;
    if (error) return <p>{error}</p>;
    if (!product) return <p>Produk tidak tersedia</p>;

    return (
        <div>
            <h2>Detail Produk</h2>
            <p><strong>ID:</strong> {product.id}</p>
            <p><strong>Nama:</strong> {product.name}</p>
            <p><strong>Harga:</strong> ${product.price}</p>
            <p><strong>Stok:</strong> {product.stock}</p>
            <Link to="/">Kembali ke Daftar Produk</Link>
        </div>
    );
};

export default ProductDetail;

Langkah 8: Membuat Komponen CreateProduct

Komponen ini akan memungkinkan pengguna untuk menambahkan produk baru.

// src/components/CreateProduct.js
import React, { useState } from 'react';
import axios from 'axios';
import { useNavigate } from 'react-router-dom';

const CreateProduct = () => {
    const [name, setName] = useState('');
    const [price, setPrice] = useState('');
    const [stock, setStock] = useState('');
    const [error, setError] = useState(null);
    const navigate = useNavigate();

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

        const newProduct = { name, price: parseFloat(price), stock: parseInt(stock) };

        axios.post('http://localhost:3000/api/products', newProduct, {
            headers: {
                'Content-Type': 'application/json'
            }
        })
            .then(() => {
                navigate('/');
            })
            .catch(() => {
                setError('Gagal menambahkan produk');
            });
    };

    return (
        <div>
            <h2>Tambah Produk Baru</h2>
            {error && <p style={{ color: 'red' }}>{error}</p>}
            <form onSubmit={handleSubmit}>
                <div>
                    <label>Nama:</label>
                    <input 
                        type="text" 
                        value={name} 
                        onChange={(e) => setName(e.target.value)} 
                        required 
                    />
                </div>
                <div>
                    <label>Harga:</label>
                    <input 
                        type="number" 
                        step="0.01" 
                        value={price} 
                        onChange={(e) => setPrice(e.target.value)} 
                        required 
                    />
                </div>
                <div>
                    <label>Stok:</label>
                    <input 
                        type="number" 
                        value={stock} 
                        onChange={(e) => setStock(e.target.value)} 
                        required 
                    />
                </div>
                <button type="submit">Tambah Produk</button>
            </form>
        </div>
    );
};

export default CreateProduct;

Langkah 9: Membuat Komponen UpdateProduct

Komponen ini akan memungkinkan pengguna untuk memperbarui data produk yang ada.

// src/components/UpdateProduct.js
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import { useNavigate, useParams } from 'react-router-dom';

const UpdateProduct = () => {
    const { id } = useParams();
    const navigate = useNavigate();

    const [name, setName] = useState('');
    const [price, setPrice] = useState('');
    const [stock, setStock] = useState('');
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState(null);

    useEffect(() => {
        axios.get(`http://localhost:3000/api/products/${id}`)
            .then(response => {
                const product = response.data;
                setName(product.name);
                setPrice(product.price);
                setStock(product.stock);
                setLoading(false);
            })
            .catch(() => {
                setError('Produk tidak ditemukan');
                setLoading(false);
            });
    }, [id]);

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

        const updatedProduct = { name, price: parseFloat(price), stock: parseInt(stock) };

        axios.put(`http://localhost:3000/api/products/${id}`, updatedProduct, {
            headers: {
                'Content-Type': 'application/json'
            }
        })
            .then(() => {
                navigate('/');
            })
            .catch(() => {
                setError('Gagal memperbarui produk');
            });
    };

    if (loading) return <p>Loading...</p>;
    if (error) return <p>{error}</p>;

    return (
        <div>
            <h2>Update Produk</h2>
            <form onSubmit={handleSubmit}>
                <div>
                    <label>Nama:</label>
                    <input 
                        type="text" 
                        value={name} 
                        onChange={(e) => setName(e.target.value)} 
                        required 
                    />
                </div>
                <div>
                    <label>Harga:</label>
                    <input 
                        type="number" 
                        step="0.01" 
                        value={price} 
                        onChange={(e) => setPrice(e.target.value)} 
                        required 
                    />
                </div>
                <div>
                    <label>Stok:</label>
                    <input 
                        type="number" 
                        value={stock} 
                        onChange={(e) => setStock(e.target.value)} 
                        required 
                    />
                </div>
                <button type="submit">Update Produk</button>
            </form>
        </div>
    );
};

export default UpdateProduct;

Langkah 10: Menambahkan Styling (Opsional)

Anda dapat menambahkan styling untuk membuat tampilan lebih menarik. Misalnya, tambahkan CSS di App.css:

/* src/App.css */
body {
    font-family: Arial, sans-serif;
    padding: 20px;
}

nav ul {
    list-style: none;
    display: flex;
    gap: 10px;
    padding: 0;
}

nav ul li {
    display: inline;
}

.container {
    margin-top: 20px;
}

table {
    width: 100%;
    border-collapse: collapse;
}

th, td {
    padding: 10px;
    text-align: left;
}

Jangan lupa untuk mengimpor App.css di App.js:

// src/App.js
import './App.css';
// ... kode lainnya

Langkah 11: Menjalankan Aplikasi

Pastikan backend API Anda berjalan di http://localhost:3000/api/products. Jika menggunakan port yang sama, Anda mungkin perlu mengubah port aplikasi React.

Untuk mengubah port, jalankan:

PORT=3001 npm start

Atau, jika Anda menggunakan Windows:

set PORT=3001 && npm start

Akses aplikasi di http://localhost:3001/.

Kesimpulan

Anda sekarang memiliki aplikasi React.js yang dapat melakukan operasi CRUD pada produk menggunakan API REST. Aplikasi ini mencakup:

  • Menampilkan daftar produk dengan opsi untuk melihat detail, mengedit, atau menghapus.

  • Menampilkan detail produk tertentu.

  • Menambahkan produk baru.

  • Memperbarui produk yang ada.

Anda dapat mengembangkan lebih lanjut aplikasi ini dengan menambahkan fitur seperti autentikasi, validasi form yang lebih kompleks, atau pagination untuk daftar produk yang besar.

Semoga tutorial ini bermanfaat! Selamat mencoba.

Last updated