Membuat Fitur-Fitur Utama CRUD Dengan React JS
Sebelumnya, kita telah membuat REST API mengenai MangaListing menggunakan Node.js dan juga Mysql sebagai database. Disana kita belajar dasar dasar bagaimana kita membuat REST API dan juga membuat Database Mysql.
Dalam tutorial ini, kami akan membahas langkah-langkah untuk membuat sebuah aplikasi web yang dapat menampilkan listing manga menggunakan React JS. pada tutorial ini kami sengaja menggunakan setup seminimal mungkin untuk memudahkan kamu yang baru masuk ke React JS. Pembuatan manga listing ini akan mencakup penggunaan React Hooks, routing dengan React Router, pengambilan data dari server, serta penggunaan form untuk menambahkan dan mengedit manga. Pembaca akan belajar bagaimana membuat tampilan yang menarik dengan CSS, serta bagaimana mengirimkan data ke server menggunakan metode HTTP POST dan PUT.
Apa yang akan kita bahas :
- Apa itu React?
- Persiapan Proyek Mangalisting
- React Router Set-Up
- Membuat Komponen Tabel
- Membuat Komponen Input
- Membuat Komponen Edit
Prerequisites
Untuk bisa mengikuti project ini, kamu harus memiliki :
- Pemahaman Mengenai HTML
- Pemahaman Bagaimana CSS Bekerja
- Pemahaman Bagaimana JavaScript Bekerja
- Logika Dasar
Tapi jangan khawatir jika kamu masih belum memiliki pemahaman seperti yang diatas, kita akan membahasnya dari awal.
Apa itu React ?
React JS atau React adalah library JavaScript populer buatan Facebook yang digunakan dalam proses pengembangan aplikasi mobile dan web. React berfungsi untuk memudahkan kita dalam mengembangkan sebuah software.
Tujuannya adalah untuk memungkinkan developer dengan mudah membuat UI yang cepat untuk situs web. Konsep utama React JS adalah Document Object Model (DOM) virtual.
React JS merupakan library JavaScript yang sangat populer karena digunakan oleh beragam platform populer seperti Facebook, Instagram, WhatsApp, Asana, Cloudflare, DropBox, Netflix, Dan Lainnya.
Kita bisa menginstall react dengan menggunakan :
npx create-react-app my-app
Persiapan Proyek Mangalisting
Sebelum menginstall React, kamu harus menginstall Node.js terlebih dahulu, kamu bisa melihat tutorialnya disini.
Setelah kamu menginstall Node.js, Bukalah Folder yang berisi projek Backend yang kemarin sudah kita buat. (Bukan Di folder mangalists)
Setelah itu Bukalah Terminal pada Folder tersebut, Dan ketikkan :
npx create-react-app mangalists-ui
Untuk memulai aplikasi React, kamu bisa menggunakan :
npm start
Kamu akan melihat Template Seperti ini :
![](https://asinkron.com/content/images/2023/10/React_Dark_BG.png)
Pastikan Project Bahwa Project Bisa dimulai. Jika kamu masih bingung bagaimana cara kita menginstall React, kita bisa ke website ini.
Setelah menginstall React, kita akan menginstall React Router DOM dengan cara :
npm install react-router-dom
Untuk Struktur Projek akan kita buat seperti ini :
![](https://asinkron.com/content/images/2023/10/Screenshot-2023-10-22-085251.png)
Tambahkan Folder dan File Tambahan seperti Gambar Diatas, Pastikan bahwa struktur Folder sama seperti diatas untuk mengikuti tutorial ini.
Untuk Kode di tabel/tabel.js
:
import React from "react";
const Tabel = () => {
return (
<></>
);
};
export default Tabel;
Untuk Kode di input/input.js
:
import React from "react";
const Input = () => {
return (
<></>
);
};
export default Input;
input/input.js
Untuk Kode di edit/edit.js
:
import React from "react";
const Edit = () => {
return (
<></>
);
};
export default Edit;
edit/edit.js
Untuk Kode di header/header.js
:
import { Link } from "react-router-dom";
import "./headerStyle.css";
const Heading = () => {
return (
<header className="header-container">
<div className="header-title">Mangalists</div>
<Link to={'/input'} className="button-wrapper">
<div>
<img src="/plus.svg" />
Add Data
</div>
</Link>
</header>
);
};
export default Heading;
header/header.js
Kode Css untuk header :
.header-container{
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
}
.header-title{
font-size: 35px;
font-weight: 500;
color: var(--text-main);
}
.button-wrapper{
display: flex;
justify-content: center;
align-items: center;
}
.button-wrapper img{
width: 20px;
height: 20px;
}
.button-wrapper div{
display: flex;
justify-content: center;
align-items: center;
gap: 5px;
padding: 10px 15px;
border-radius: 8px;
background-color: var(--secondary);
color: white;
font-weight: 500;
}
React Router Set-Up
React Router adalah salah satu package yang sangat populer dalam ekosistem React yang memungkinkan pengembang web untuk membuat aplikasi yang memiliki navigasi dan routing. Kita akan membahas penggunaan React Router dalam sebuah aplikasi React dengan kode yang sudah disediakan. Mari kita telaah lebih dalam tentang bagaimana kode tersebut berfungsi dan mengapa itu penting dalam pengembangan aplikasi berbasis React.
Buka index.js
, Dan masukkan kode berikut ini :
import React from "react";
import ReactDOM from "react-dom/client";
import { createBrowserRouter, RouterProvider } from "react-router-dom";
import "./index.css";
import App from "./App";
import Edit from "./components/edit/edit";
import Tabel from "./components/tabel/tabel";
import Input from "./components/input/input";
const router = createBrowserRouter([
{
path: "/",
element: <App />,
children: [
{ index: true, element: <Tabel /> },
{
path: "edit/:editId",
element: <Edit />,
},
{
path: "input",
element: <Input />
}
],
}
]);
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<RouterProvider router={router} />
</React.StrictMode>
);
Pembahasan kode :
- Impor Modul: Kode pertama adalah impor modul yang dibutuhkan.
createBrowserRouter
,RouterProvider
, dan komponen React lainnya seperti App,Edit
,Tabel
, danInput
diimpor ke dalam file ini. - Konfigurasi Router: Kode berikutnya adalah pengaturan konfigurasi router. Di sini, kita menggunakan createBrowserRouter untuk membuat objek router. Ini mendefinisikan aturan-aturan navigasi dalam aplikasi kita.
- Aturan Navigasi: Di dalam konfigurasi router, kita mendefinisikan aturan-aturan navigasi. Aturan-aturan ini menentukan komponen mana yang harus ditampilkan saat URL berubah. Misalnya, / akan menampilkan komponen App, dan
/edit/:editId
akan menampilkan komponenEdit
dengan parameter editId. - Render Aplikasi: Akhirnya, kita menggunakan ReactDOM.createRoot untuk membuat root aplikasi React. Kemudian, kita menggunakan RouterProvider untuk menghubungkan router dengan aplikasi kita.
Buka App.js
, Dan masukkan kode berikut ini :
import { Outlet } from "react-router-dom";
import "./App.css"
import Heading from "./components/header/header";
function App() {
return (
<div className="app">
<Heading />
<Outlet />
</div>
);
}
export default App;
Kode di atas adalah komponen App
dalam aplikasi React.Kamu memiliki beberapa komponen yang di-render di dalamnya. Berikut penjelasan beberapa bagian pentingnya:
-
import { Outlet } from "react-router-dom";
: Di sini, Kita mengimpor komponenOutlet
dari React Router. KomponenOutlet
adalah tempat di mana komponen yang sesuai dengan rute saat ini akan ditampilkan. -
import "./App.css"
: Ini adalah impor untuk file CSS terkait dengan komponenApp
. -
Di dalam fungsi
App
, Kita mereturn elemen JSX yang berisi<Heading />
dan<Outlet />
.
Penggunaan <Outlet />
menunjukkan bahwa Kita merencanakan untuk menggunakan React Router untuk menangani rute dalam aplikasi. Komponen-komponen yang sesuai dengan rute tertentu akan ditampilkan di tempat ini, tergantung pada rute yang sedang aktif.
Jika kalian masih kurang paham soal React Router, kalian bisa membaca referensi yang kami buat disini.
Membuat Komponen Tabel
Kode untuk tabel/tabel.js
Langkah 1: Import dan State
Pada langkah ini, kita mengimpor dependensi yang diperlukan, seperti useState
, useEffect
, dan Link
dari React dan React Router. Selain itu, kita menginisialisasi dua state: data
untuk menyimpan data manga yang diambil dari server, dan error
untuk menangani kesalahan jika terjadi.
import { useState, useEffect } from "react";
import "./tabelStyle.css";
import { Link } from "react-router-dom";
const Tabel = (props) => {
const [data, setdata] = useState();
const [error, setError] = useState();
const [loading, setloading] = useState(false);
useEffect(() => {
fetch("http://localhost:3001/mangalist")
.then((res) => {
if (!res.ok) {
throw Error("Cannot Fetch The End Point..");
}
setloading(true);
return res.json();
})
.then((data) => {
const datas = data && data.data;
setloading(false);
setdata(datas);
})
.catch((err) => {
setError(err.message);
});
}, []);
Langkah 2: Fungsi handleDelete
Pada langkah ini, kita mendefinisikan fungsi handleDelete
yang digunakan untuk menghapus data manga berdasarkan ID. Saat data manga berhasil dihapus, kita akan mengambil data manga lagi dari server.
const handleDelete = async (id) => {
// Menghapus data manga berdasarkan ID
fetch(`http://localhost:3001/mangalist/${id}`, {
method: "DELETE",
})
.then((response) => {
if (response.status === 200) {
console.log("Data deleted successfully.");
// Mengambil data manga lagi setelah menghapus
fetch("http://localhost:3001/mangalist")
.then((res) => {
if (!res.ok) {
throw Error("Cannot Fetch The End Point..");
}
return res.json();
})
.then((data) => {
const datas = data && data.data;
setdata(datas);
})
.catch((err) => {
setError(err.message);
});
} else {
console.error("Failed to delete data.");
}
})
.catch((error) => {
console.error("Error:", error);
});
};
Langkah 3: Fungsi dateConvert
Fungsi dateConvert
digunakan untuk mengonversi format tanggal dari string lengkap menjadi hanya tanggal. Ini dilakukan dengan mengambil substring 10 karakter pertama dari string tanggal.
function dateConvert(params) {
// Membuat objek tanggal dari tahun, bulan, dan hari yang telah diparse
const date = params.substring(0, 10);
return date;
}
Langkah 4: Render Tabel
Pada langkah ini, kita merender tabel yang menampilkan data manga yang telah diambil dari server. Jika data tersedia, kita melakukan pemetaan dan membuat baris tabel untuk setiap Manga. Jika tidak ada data yang tersedia, kita menampilkan pesan "Loading..." dalam satu baris tabel.
return (
<div className="table-container">
<div className="table-card">
<table className="custom-table">
<thead>
<tr>
<th>Judul</th>
<th>Jumlah Volume</th>
<th>Penerbit</th>
<th>Penulis</th>
<th>Rating</th>
<th>Tanggal Rilis</th>
<th>Url</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{data && (
data.map((manga) => (
<tr key={manga.id} className="table-row">
<td>{manga.judul}</td>
<td>{manga.jumlah_volume}</td>
<td>{manga.penerbit}</td>
<td>{manga.penulis}</td>
<td>{manga.rating}</td>
<td>{dateConvert(manga.tanggal_rilis)}</td>
<td>
<a href={manga.url_baca}>{manga.url_baca}</a>
</td>
<td>
<div className="wrapper">
<Link to={`edit/${manga.id}`}>
<img src="/brush.svg" />
</Link>
<div onClick={() => handleDelete(manga.id)}>
<img src="/trash.svg" />
</div>
</div>
</td>
</tr>
))
)}
</tbody>
</table>
{loading && <div>Loading...</div>}
{error && <div>Error Terjadi</div>}
</div>
</div>
);
};
Dalam langkah ini, kita merender tabel dengan data manga yang sudah diambil dari server. Data manga diambil dari state data
dan ditampilkan dalam baris-baris tabel. Jika data masih dimuat (atau data kosong), pesan "Loading..." akan ditampilkan. Setiap baris tabel memiliki tombol Edit dan tombol Delete yang mengarahkan ke halaman Edit dan mengeksekusi fungsi handleDelete
, masing-masing.
Untuk Kode Css pada tabel/tabelStyle.css
:
.table-container {
border-radius: 10px;
padding: 10px 20px;
background-color: white;
}
.table-container table {
color: var(--text-main);
width: 100%;
}
/* tabelStyle.css */
.table-container {
padding: 10px 20px;
background-color: white;
margin: 20px; /* Add margin for the entire table container */
}
.custom-table {
width: 100%;
border-collapse: collapse;
border-radius: 10px;
font-family: Arial, sans-serif;
background-color: #fff;
}
.custom-table th {
color: var(--text-main);
text-align: left;
padding: 20px;
border-bottom: 2px solid #ddd;
}
.custom-table td {
padding: 15px;
border-bottom: 2px solid #ddd;
}
.custom-table td .wrapper{
display: flex;
align-items: center;
justify-content: space-between;
}
.custom-table img{
height: 20px;
width: 20px;
}
.table-row {
margin-bottom: 50px; /* Add margin between <tr> elements */
}
Begini hasil yang di harapkan :
![](https://asinkron.com/content/images/2023/10/screencapture-localhost-3000-2023-10-23-09_16_59.png)
Membuat Komponen Input
Kode untuk input/input.js
:
Kode komponen Input
adalah komponen yang digunakan untuk mengambil input dari pengguna dan mengirimnya ke server untuk membuat data manga baru. Berikut adalah penjelasan setiap bagian kode:
Langkah 1: Import dan State
Pertama, kita mengimpor dependensi yang diperlukan seperti useState
, useNavigate
dari React dan React Router. Selain itu, kita menginisialisasi state formData
yang digunakan untuk menyimpan data input dari pengguna, seperti judul, jumlah volume, dll.
import React, { useState } from "react";
import "./inputStyle.css";
import { useNavigate } from "react-router-dom";
const Input = () => {
// State untuk menyimpan data form
const [formData, setFormData] = useState({
judul: "",
penulis: "",
penerbit: "",
tanggal_rilis: "",
rating: "",
jumlah_volume: "",
url_baca: "",
});
const navigate = useNavigate();
Langkah 2: Fungsi handleInputChange
Kita mendefinisikan fungsi handleInputChange
yang digunakan untuk meng-update state formData
ketika nilai input berubah. Ini memungkinkan kita untuk menyimpan nilai yang dimasukkan oleh pengguna.
// Fungsi untuk mengupdate state formData saat input fields berubah
const handleInputChange = (event) => {
const { name, value } = event.target;
setFormData({
...formData,
[name]: value,
});
};
Langkah 3: Fungsi removeHyphens
Kita mendefinisikan fungsi removeHyphens
yang digunakan untuk menghapus tanda hubung (-
) dari string tanggal. Ini diperlukan karena format input tanggal yang biasanya menggunakan tanda hubung.
function removeHyphens(inputString) {
return inputString.replace(/-/g, "");
}
Langkah 4: Fungsi handleSubmit
Fungsi handleSubmit
dipanggil ketika pengguna mengirimkan form. Pertama, kita memeriksa apakah nilai jumlah volume dan rating lebih besar dari 0. Jika tidak, kita menampilkan pesan kesalahan dan mengosongkan form.
Jika semua validasi berhasil, kita menghapus tanda hubung dari string tanggal dan menyimpan data dalam newFormData
. Kemudian, kita mengirim data ke server menggunakan metode POST.
Jika permintaan berhasil, kita mengosongkan form dan melakukan navigasi kembali ke halaman utama. Jika ada kesalahan dalam permintaan, kita menampilkan pesan kesalahan.
const handleSubmit = async (event) => {
event.preventDefault();
if (
formData.jumlah_volume <= 0 ||
formData.rating <= 0
) {
alert("Nilai harus di atas 0.");
setFormData({
judul: "",
jumlah_volume: "",
penerbit: "",
penulis: "",
rating: "",
tanggal_rilis: "",
url_baca: "",
});
return;
}
function removeHyphens(inputString) {
return inputString.replace(/-/g, "");
}
const dateWithoutHyphens = Number(removeHyphens(formData.tanggal_rilis));
const newFormData = {
...formData,
tanggal_rilis: dateWithoutHyphens,
};
try {
const response = await fetch("http://localhost:3001/mangalist", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(newFormData),
});
if (response.ok) {
setFormData({
judul: "",
jumlah_volume: "",
penerbit: "",
penulis: "",
rating: "",
tanggal_rilis: "",
url_baca: "",
});
navigate("/");
} else {
console.error("Failed to post data.");
}
const data = await response.json();
if (data.message === "Manga created successfully") {
navigate("/");
} else {
alert(data.message);
}
} catch (error) {
console.error("Error:", error);
}
};
Langkah 5: Render Form
Terakhir, kita merender form yang memungkinkan pengguna untuk memasukkan data manga. Form ini termasuk input untuk judul, jumlah volume, penerbit, penulis, rating, tanggal rilis, dan URL baca. Ketika pengguna mengisi form dan mengklik tombol "Submit," fungsi handleSubmit
akan dipanggil.
return (
<div className="input-container">
<form className="input-card" onSubmit={handleSubmit}>
<div className="form-group">
<input
required
placeholder="Judul Manga"
type="text"
id="judul"
name="judul"
value={formData.judul}
onChange={handleInputChange}
/>
</div>
<div className="form-group">
<input
required
placeholder="Jumlah Volume"
type="number"
id="jumlah_volume"
name="jumlah_volume"
value={formData.jumlah_volume}
onChange={handleInputChange}
/>
</div>
<div className="form-group">
<input
required
placeholder="Penerbit"
type="text"
id="penerbit"
name="penerbit"
value={formData.penerbit}
onChange={handleInputChange}
/>
</div>
<div className="form-group">
<input
required
placeholder="Penulis"
type="text"
id="penulis"
name="penulis"
value={formData.penulis}
onChange={handleInputChange}
/>
</div>
<div className="form-group">
<input
required
placeholder="Rating"
type="number"
id="rating"
name="rating"
value={formData.rating}
onChange={handleInputChange}
/>
</div>
<div className="form-group">
<input
required
placeholder="Tanggal Rilis"
type="date"
id="tanggal_rilis"
name="tanggal_rilis"
value={formData.tanggal_rilis}
onChange={handleInputChange}
/>
</div>
<div className="form-group">
<input
required
placeholder="Url Baca"
type="url_baca"
id="url_baca"
name="url_baca"
value={formData.url_baca}
onChange={handleInputChange}
/>
</div>
<button type="submit">Submit</button>
<button onClick={()=>navigate("/")}>Back</button>
</form>
</div>
);
};
export default Input;
Ini adalah penjelasan untuk komponen Input
dalam aplikasi React. Komponen ini mengizinkan pengguna untuk menambahkan data manga baru ke server. Juga, kita telah menambahkan validasi yang memastikan data yang dimasukkan oleh pengguna valid sebelum dikirim ke server. Jika validasi gagal, pengguna akan menerima pesan kesalahan.
Untuk Kode Css pada input/inputStyle.css
:
.input-card{
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.input-card{
border-radius: 10px;
padding: 10px 20px;
background-color: white;
}
.input-card .form-group{
margin-bottom: 10px;
}
input {
border: silver solid 2px;
border-radius: 10px;
background: 0;
outline: none;
width: 80vw;
max-width: 400px;
font-size: 1.5em;
transition: padding 0.3s 0.2s ease;
&:focus {
padding-bottom: 5px;
}
&:focus + .line {
&:after {
transform: scaleX(1);
}
}
}
Begini Hasil yang diharapkan :
![](https://asinkron.com/content/images/2023/10/screencapture-localhost-3000-input-2023-10-23-09_18_17.png)
Membuat Komponen Edit
Komponen Edit
ini digunakan untuk mengedit data manga yang sudah ada.
Berikut adalah penjelasan langkah demi langkah dari kode komponen Edit
:
Langkah 1: Import dan State
import { useState, useEffect } from "react";
import { useParams, useNavigate } from "react-router-dom";
const Edit = () => {
const { editId } = useParams();
const params = Number(editId);
// State untuk menyimpan data form
const [formData, setFormData] = useState({
judul: "",
penulis: "",
penerbit: "",
tanggal_rilis: "",
rating: "",
jumlah_volume: "",
url_baca: "",
});
- Pada langkah pertama, kita mengimpor dependensi yang diperlukan, seperti
useState
,useEffect
,useParams
, danuseNavigate
dari React dan React Router. - Kita mendefinisikan parameter
editId
yang diperoleh dari React Router'suseParams
untuk mengetahui manga mana yang akan diedit. Nilai ini dikonversi menjadi angka dan disimpan dalam variabelparams
. - Kita inisialisasi state
formData
untuk menyimpan data manga yang akan diedit.
Langkah 2: Mengambil Data Manga untuk Diedit
useEffect(() => {
fetch("http://localhost:3001/mangalist")
.then((res) => {
if (!res.ok) {
throw Error("Cannot Fetch The End Point..");
}
return res.json();
})
.then((data) => {
const datas = data && data.data;
if (datas && datas.length > 0) {
const singleManga = datas.find((manga) => manga.id === params);
const newTanggal_rilis = singleManga.tanggal_rilis.substring(0, 10);
setFormData({
judul: singleManga.judul,
penulis: singleManga.penulis,
penerbit: singleManga.penerbit,
tanggal_rilis: newTanggal_rilis,
rating: singleManga.rating,
jumlah_volume: singleManga.jumlah_volume,
url_baca: singleManga.url_baca,
});
}
})
.catch((err) => {
console.log(err.message);
});
}, []);
- Kita menggunakan
useEffect
untuk menjalankan kode untuk mengambil data manga yang akan diedit dari server. Kita request ke endpointhttp://localhost:3001/mangalist
dan mengambil responnya. - Jika permintaan berhasil, kita mencari manga yang sesuai dengan
params
(ID manga yang akan diedit) dalam data yang diterima. Jika ditemukan, kita memformat tanggal rilis dan mengisi stateformData
dengan nilai dari manga yang akan diedit.
Langkah 3: Mengirim Data Yang sudah di Edit
const navigate = useNavigate();
const handleSubmit = async (event) => {
event.preventDefault();
if (formData.jumlah_volume <= 0 || formData.rating <= 0) {
alert("Nilai harus di atas 0.");
setFormData({
judul: "",
jumlah_volume: "",
penerbit: "",
penulis: "",
rating: "",
tanggal_rilis: "",
url_baca: "",
});
return;
}
function removeHyphens(inputString) {
return inputString.replace(/-/g, "");
}
const dateWithoutHyphens = Number(removeHyphens(formData.tanggal_rilis));
const newFormData = {
...formData,
tanggal_rilis: dateWithoutHyphens,
};
try {
const response = await fetch(
`http://localhost:3001/mangalist/${params}`,
{
method: "PUT",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(newFormData),
}
);
if (response.ok) {
setFormData({
judul: "",
jumlah_volume: "",
penerbit: "",
penulis: "",
rating: "",
tanggal_rilis: "",
url_baca: "",
});
navigate("/");
} else {
console.error("Failed to post data.");
}
const data = await response.json();
if (data.message === "Manga created successfully") {
navigate("/");
} else {
alert(data.message);
}
} catch (error) {
console.error("Error:", error);
}
};
- Kita mendefinisikan fungsi
handleSubmit
, yang akan dipanggil ketika pengguna mengirimkan form. Pada fungsi ini, Kita memeriksa apakah data yang dimasukkan valid (jumlah volume dan rating di atas 0). - Jika data tidak valid, kita menampilkan pesan kesalahan dan mengosongkan form.
- Jika data valid, kita menghapus tanda hubung dari tanggal rilis, dan mengirimkan data yang telah diubah ke server menggunakan metode PUT.
- Jika permintaan berhasil, kita mengosongkan form dan melakukan navigasi kembali ke halaman utama. Jika ada kesalahan dalam request, kita menangani kesalahan tersebut.
Langkah 4: Mengatur Perubahan State
const handleInputChange = (event) => {
const { name, value } = event.target;
setFormData({
...formData,
[name]: value,
});
};
Langkah 5: Render Form
return (
<div className="input-container">
<form className="input-card" onSubmit={handleSubmit}>
<div className="form-group">
<input
required
placeholder="Judul Manga"
type="text"
id="judul"
name="judul"
value={formData.judul}
onChange={handleInputChange}
/>
</div>
<div className="form-group">
<input
required
placeholder="Jumlah Volume"
type="number"
id="jumlah_volume"
name="jumlah_volume"
value={formData.jumlah_volume}
onChange={handleInputChange}
/>
</div>
<div className="form-group">
<input
required
placeholder="Penerbit"
type="text"
id="penerbit"
name="penerbit"
value={formData.penerbit}
onChange={handleInputChange}
/>
</div>
<div className="form-group">
<input
required
placeholder="Penulis"
type="text"
id="penulis"
name="penulis"
value={formData.penulis}
onChange={handleInputChange}
/>
</div>
<div className="form-group">
<input
required
placeholder="Rating"
type="number"
id="rating"
name="rating"
value={formData.rating}
onChange={handleInputChange}
/>
</div>
<div className="form-group">
<input
required
placeholder="Tanggal Rilis"
type="date"
id="tanggal_rilis"
name="tanggal_rilis"
value={formData.tanggal_rilis}
onChange={handleInputChange}
/>
</div>
<div className="form-group">
<input
required
placeholder="Url Baca"
type="url_baca"
id="url_baca"
name="url_baca"
value={formData.url_baca}
onChange={handleInputChange}
/>
</div>
<button type="submit">Submit</button>
<button onClick={() => navigate("/")}>Back</button>
</form>
</div>
);
};
export default Edit;
Untuk Kode Css, Kita Tidak perlu membuatnya karena kita memakai template yang ada di Input.
Begini Hasil yang diharapkan :
![](https://asinkron.com/content/images/2023/10/screencapture-localhost-3000-edit-2-2023-10-23-09_19_20.png)
Source dari projek ini dapat kamu temukan di https://github.com/asinkronidn/frontend-direktori-manga-react-js bantu support dengan memberi bintang ya 🤩
Kesimpulan
Sekarang kita telah membuat Front-End dari proyek MangaListing menggunakan React JS. Di tutorial kali ini, kita akan belajar bagaimana membuat struktur folder, merancang antarmuka pengguna (UI), dan mengambil data dari API.
Tutorial ini akan memberikan dasar-dasar yang kuat bagi teman-teman yang ingin memulai karir sebagai pengembang web. Dengan menguasai konsep-konsep dasar seperti struktur folder, pembuatan UI, dan interaksi dengan API, Teman - teman akan siap untuk menjelajahi proyek-proyek yang lebih kompleks dan membangun aplikasi web yang lebih kuat.
Tetap semangat dalam perjalanan pengembangan web Kamu, dan jangan ragu untuk bertanya jika ada pertanyaan lebih lanjut atau bantuan yang Kamu butuhkan. Semangat Koding : )
#InJavascriptWeTrust
![](https://asinkron.com/content/images/size/w2000/2023/11/3-Langkah-Mudah-Install-Tailwind-CSS-Di-React.js-1.png)
Selanjutnya 3 Langkah Mudah Install Tailwind CSS Di React JS
![](/assets/images/join-discord-official-asinkron-indonesia-3.png)
Silahkan Login/Sign Up
😞 Discord eklusif buat member asinkron.com
Jangan khawatir silahkan Daftar GRATIS 😎
*Link discord akan dikirim ke email yang anda gunakan untuk mendaftar.