Tutorial React TypeScript #3: Menampilkan Data dari Rest API


Tutorial React TypeScript #3: Menampilkan Data dari Rest API

Halo teman-teman semuanya, di artikel sebelumnya, kita telah berhasil menginstall dan mengkonfigurasi React Router. Sekarang, kita akan melangkah lebih jauh dengan menampilkan data dari REST API di React menggunakan TypeScript.

Dalam tutorial ini, kita akan belajar:

  • Installasi dan Konfigurasi Axios.
  • Bagaimana cara mengambil data dari API menggunakan Axios.
  • Cara menggunakan useEffect dan useState untuk mengelola data.
  • Menampilkan data di dalam component React dengan TypeScript.
  • Membuat Route untuk menampilkan halaman products.

Langkah 1 - Installasi Axios

Langkah pertama yang harus kita lakukan adalah menginstall library tambahan yang bernama Axios. Library ini digunakan untuk melakukan Http request ke server dengan lebih mudah dan cepat.

Silahkan teman-teman jalankan perintah berikut ini di dalam terminal/CMD dan pastikan sudah berada di dalam project React-nya.

npm install axios@1.8.4

Silahkan tunggu proses installasinya sampai selesai dan pastikan teman-teman terhubung dengan internet.

Langkah 2 - Konfigurasi Endpoint API

Setelah menginstal Axios, langkah selanjutnya adalah membuat instance Axios agar lebih mudah mengelola perubahan domain API. Dengan ini, kita hanya perlu mengubah satu baris kode saat ada perubahan, tanpa harus mengganti alamat API di banyak tempat.

Silahkan teman-teman buat folder dengan nama api di dalam folder src, kemudian tambahkan file index.tsx dan masukkan kode berikut ini di dalamnya.

src/api/index.tsx

//import axios
import axios from 'axios';

const Api = axios.create({
    //set default endpoint API
    baseURL: 'http://localhost:8000'
})

export default Api

Coba teman-teman perhatikan dari penambahan kode di atas, pada bagian baseURL itu merupakan alamat domain dari project Laravel.

Langkah 3 - Menampilkan Data dari Rest API

Silahkan teman-teman buat folder baru dengan nama products di dalam folder src/views, kemudian di dalam folder products silahkan buat file baru dengan nama index.tsx dan masukkan kode berikut ini di dalamnya.

src/views/products/index.tsx

//import Type FC dan hook useState dan useEffect dari React
import { FC, useState, useEffect } from "react";

//import api dari folder api
import Api from "../../api";

//import Link dari react-router
import { Link } from "react-router";

// Interface Product
interface Product {
    id: number;
    image: string;
    title: string;
    description: string;
    price: number;
    stock: number;
}

const ProductIndex: FC = () => {

    // init state products
    const [products, setProducts] = useState<Product[]>([]);

    // Fetch data products dari API
    const fetchDataProducts = async () => {
        try {

            // Fetch data products
            const response = await Api.get("/api/products");

            // Set data products ke state
            setProducts(response.data.data.data);

        } catch (error) {

            // Log error
            console.error("Error fetching products:", error);
        }
    };

    // useEffect
    useEffect(() => {

        // call fetchDataProducts
        fetchDataProducts();

    }, []);

    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">
                            <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>
                                    {products.length > 0 ? (
                                        products.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 className="btn btn-sm btn-danger rounded-5 shadow border-0">
                                                        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 penambahan kode di atas, pertama kita import Type FC, hook useState dan useEffect dari React.

//import Type FC dan hook useState dan useEffect dari React
import { FC, useState, useEffect } from "react";

Kemudian kita import service API yang sudah kita buat sebelumnya.

//import api dari folder api
import Api from "../../api";

Karena nanti ada navigasi untuk perpindahan halaman, maka kita import Link dari React Router.

//import Link dari react-router
import { Link } from "react-router";

Selanjutnya, kita membuat sebuah interface yang bernama Product.

// Interface Product
interface Product {
    id: number;
    image: string;
    title: string;
    description: string;
    price: number;
    stock: number;
}

Interface di atas digunakan untuk mendefinisikan struktur data product yang diterima dari API dan memastikan bahwa setiap product memiliki tipe data yang sesuai.

Setelah itu, di dalam function component ProductIndex, kita membuat inisialisasi state yang bernama products. State ini akan digunakan untuk menampung data dari Rest API.

// init state products
const [products, setProducts] = useState<Product[]>([]);

Pada deklarasi state di atas, kita menggunakan interface Product sebagai tipe data untuk memastikan bahwa data yang disimpan di dalam state harus sesuai dengan struktur yang telah didefinisikan dalam interface. Dengan cara ini, setiap item dalam array products akan mengikuti format yang sudah ditentukan, sehingga lebih aman dan terstruktur.

Kemudian kita membuat function baru dengan nama fetchDataProducts.

// Fetch data products dari API
const fetchDataProducts = async () => {

	//...
	
}

Di dalamnya, kita melakukan fetch ke backend melalui REST API dengan endpoint /api/products dan method yang digunakan adalah GET.

// Fetch data products
const response = await Api.get("/api/products");

Jika berhasil, maka kita akan assign response data-nya ke dalam state products.

// Set data products ke state
setProducts(response.data.data.data);

Agar function fetchDataProducts bisa dijalankan saat halaman dibuka, maka kita perlu memanggilnya di dalam hook useEffect.

// useEffect
useEffect(() => {

	// call fetchDataProducts
	fetchDataProducts();

}, []);

Dan untuk menampilkan data di dalam JSX, kita menggunakan sebuah kondisi untuk memastikan apakah ada datanya atau tidak.

{
    products.length > 0

    ?  //looping

    : // Data Belum Tersedia !

}

Jika data di atas 0, maka kita akan melakukan perulangan data menggunakan map untuk menampilkan data.

products.map((product) => (

	//...
	
))

Langkah 4 - Konfigurasi Route Products Index

Kita lanjutkan untuk membuat konfigurasi route-nya, sehingga nanti halama products bisa ditamilkan di dalam aplikasi.

Silahkan buka file src/routes/index.tsx, kemudian ubah kode-nya menjadi seperti berikut ini.

src/routes/index.tsx

// Import FC from React
import { FC } from "react";

// Import React Router
import { Routes, Route } from "react-router";

// Import view HomePage
import Home from "../views/home";

// Import view ProductIndex
import ProductIndex from "../views/products/index";

// Definisikan component dengan Type FC (Functional Component)
const RoutesIndex: FC = () => {
    return (
        <Routes>
            {/* Route untuk halaman utama */}
            <Route path="/" element={<Home />} />

            {/* Route untuk halaman products */}
            <Route path="/products" element={<ProductIndex />} />
        </Routes>
    );
};

export default RoutesIndex;

Dari perubahan kode di atas, pertama kita import view products index.

// Import view ProductIndex
import ProductIndex from "../views/products/index";

Kemudian kita membuat konfigurasi route-nya.

{/* Route untuk halaman products */}
<Route path="/products" element={<ProductIndex />} />

Langkah 5 - Uji Coba Menampilkan Data

Setelah semua berhasil dibuat, sekarang kita akan lakukan uji coba di dalam browser untuk melihat hasilnya, silahkan teman-teman klik menu PRODUCTS yang ada di navbar.

Atau bisa juga ke URL berikut ini http://localhost:5173/products, jika berhasil maka akan menampilkan hasil seperti berikut.

Keismpulan

Pada artikel ini, kita semua telah belajar banyak hal, seperti installasi dan konfigurasi Axios, kemudian menampilkan data dari Rest API menggunakan TypeScript di React, membuat konfigurasi route untuk menampilkan halaman products.

Pada artikel selanjutnya, kita semua akan belajar bagaimana cara melakukan proses insert dan upload gambar di React TypeScript menggunakan Rest API.

Terima Kasih


Fika Ridaul Maulayya
Full-Stack Developer, Content Creator and CO-Founder SantriKoding.com

Suka dengan tulisan di SantriKoding? Kamu bisa memberikan dukungan dengan berdonasi atau bagikan konten ini di sosial media. Terima kasih atas dukungan Anda!

KEBIJAKAN KOMENTAR

Saat memberikan komenatar silahkan memberikan informasi lengkap tentang error, seperti: screenshot, link kode, dll. Baca aturan komentar kami