Halo teman-teman semuanya, setelah sebelumnya berhasil menampilkan data di Astro menggunakan React, maka kita sekarang akan belajar bagaimana cara melakukan proses insert dan upload gambar di Astro menggunakan React.
Langkah 1 - Membuat Component Post Create (React)
Silahkan teman-teman buat file baru dengan nama PostCreate.jsx
di dalam folder src/components
, kemudian masukkan kode berikut ini di dalamnya.
//import useState
import { useState } from "react";
//import API
import api from "../services/api";
export default function PostCreate() {
//define state
const [image, setImage] = useState("");
const [title, setTitle] = useState("");
const [content, setContent] = useState("");
//state validation
const [errors, setErrors] = useState([]);
//method handle file change
const handleFileChange = (e) => {
setImage(e.target.files[0]);
};
//method store post
const storePost = async (e) => {
e.preventDefault();
//init FormData
const formData = new FormData();
//append data
formData.append("image", image);
formData.append("title", title);
formData.append("content", content);
//send data with API
await api
.post("/api/posts", formData)
.then(() => {
//redirect to posts index
window.location.href = "/posts";
})
.catch((error) => {
//set errors response to state "errors"
setErrors(error.response.data);
});
};
return (
<div className="container mt-5">
<div className="row">
<div className="col-md-12">
<div className="card border-0 rounded shadow">
<div className="card-body">
<form onSubmit={storePost}>
<div className="mb-3">
<label className="form-label fw-bold">Image</label>
<input
type="file"
onChange={handleFileChange}
className="form-control"
/>
{errors.image && (
<div className="alert alert-danger mt-2">
{errors.image[0]}
</div>
)}
</div>
<div className="mb-3">
<label className="form-label fw-bold">Title</label>
<input
type="text"
className="form-control"
onChange={(e) => setTitle(e.target.value)}
placeholder="Title Post"
/>
{errors.title && (
<div className="alert alert-danger mt-2">
{errors.title[0]}
</div>
)}
</div>
<div className="mb-3">
<label className="form-label fw-bold">Content</label>
<textarea
className="form-control"
onChange={(e) => setContent(e.target.value)}
rows="5"
placeholder="Content Post"
></textarea>
{errors.content && (
<div className="alert alert-danger mt-2">
{errors.content[0]}
</div>
)}
</div>
<button
type="submit"
className="btn btn-md btn-primary rounded-sm shadow border-0"
>
Save
</button>
</form>
</div>
</div>
</div>
</div>
</div>
);
}
Dari perubahan kode di atas, pertama kita import useState
dari React.
//import useState
import { useState } from 'react';
Karena akan berinterasksi dengan API, maka kita import konfigurasi API yang sudah kita buat sebelumnya.
//import API
import api from "../services/api";
Di dalam function component PostCreate
kita membuat beberapa state, yang mana nanti digunakan untuk menampung data yang diinput di dalam form.
//define state
const [image, setImage] = useState('');
const [title, setTitle] = useState('');
const [content, setContent] = useState('');
//state validation
const [errors, setErrors] = useState([]);
Kemudian kita buat method baru dengan nama handleFileChange
. Method ini yang digunakan untuk memasukkan file yang diambil dari komputer ke dalam state image
.
//method handle file change
const handleFileChange = (e) => {
setImage(e.target.files[0]);
}
Method handleFileChange
di atas akan dijalankan, ketika input file gambar di dalam form dipilih.
<input type="file" onChange={handleFileChange} className="form-control"/>
Setelah itu, kita buat method lagi dengan nama storePost
. Method ini akan dijalankan ketika form disubmit.
<form onSubmit={storePost}>
//...
</form>
//method store post
const storePost = async (e) => {
//...
}
Di dalam method storePost
di atas, pertama kita inisialisasi FormData
. Karena kita akan melakukan upload gambar, maka kita harus menggunakan FormData
agar file bisa dikirim ke server.
//init FormData
const formData = new FormData();
Setelah berhasil di inisialisasi, langkah berikutnya adalah memasukkan data yang ada di dalam state ke dalam FormData
, yaitu dengan menggunakan append
.
//append data
formData.append('image', image);
formData.append('title', title);
formData.append('content', content);
Setelah data berhasil dimasukkan ke dalam FormData
, langkah berikutnya adalah melakukan kirim data menggunakan Rest API dengan bantuan Axios
, yaitu menggunakan method POST
.
//send data with API
await api.post('/api/posts', formData)
Jika proses insert dan upload data berhasil dilakukan di dalam server, maka kita akan redirect ke dalam halaman posts index.
//redirect to posts index
window.location.href = "/posts";
Tapi jika data gagal disimpan, maka kita akan memasukkan error response validasi ke dalam state yang bernama errors
.
//set errors response to state "errors"
setErrors(error.response.data);
Dan untuk menampilkan error di dalam template, kita bisa menggunakan kode seperti berikut ini.
{
errors.image && (
<div className="alert alert-danger mt-2">
{errors.image[0]}
</div>
)
}
Langkah 2 - Menampilkan Form Post Create di Astro
Sekarang kita akan lanjutkan menampilkan form yang sudah kita buat di atas di dalam Astro. Silahkan teman-teman buat folder baru dengan nama create
di dalam folder src/pages/posts
dan di dalam folder create
silahkan buat file baru dengan nama index.astro
, kemudian masukkan kode berikut ini di dalamnya.
---
//import transitions effect
import { ViewTransitions } from "astro:transitions";
//import layout
import MainLayout from "../../../layouts/MainLayout.astro";
//import from create post
import PostCreate from "../../../components/PostCreate.jsx";
---
<MainLayout>
<ViewTransitions />
<div class="container mb-5" style="margin-top: 5rem;">
<div class="row">
<div class="col-md-12">
<PostCreate client:load />
</div>
</div>
</div>
</MainLayout>
Dari penambahan kode di atas, pertama kita import ViewTransitions
dari Astro. Ini digunakan agar aplikasi kita bisa berjalan secara SPA.
//import transitions effect
import { ViewTransitions } from "astro:transitions";
Setelah itu, kita tinggal memanggilnya di dalam layout.
<ViewTransitions />
Kemudian kita import juga MainLayout
yang mana merupakan induk template dari aplikasi kita.
//import layout
import MainLayout from "../../layouts/MainLayout.astro";
Setelah itu, kita import component PostCreate
yang sudah kita buat sebelumnya.
//import from create post
import PostCreate from "../../../components/PostCreate.jsx";
Dan untuk menampilkannya, kita cukup seperti berikut ini.
<PostCreate client:load />
Langkah 3 - Uji Coba Insert Data
Silahkan teman-teman klik button ADD NEW POST
, jika berhasil maka akan menampilkan halaman seperti berikut ini.
Silahkan klik button Save
tanpa mengisi data apapun di dalam form, maka kita akan mendapatkan error validasi seperti berikut ini.
Dan sekarang jika teman-teman isi semua data-nya di dalam form, jika berhasil maka kita akan di arahkan ke halaman post index dengan menampilkan data yang baru saja diinsert.
Kesimpulan
Pada artikel ini kita semua telah belajar bagaimana cara membuat form tambah data di dalam Astro menggunakan component React. Pada artikel berikutnya kita semua akan belajar bagaimana cara membuat proses edit dan update data di dalam Astro dan React.
Terima Kasih