Pada project kali ini, kita akan membuat beberapa component menggunkan react js
, tujuannya agar kita dapat membuat reusable UI (User Interface) yang dapat digunakan secara fleksibel. Component juga dapat digunakan untuk memisahkan logika tampilan dan logika dari apilkasi utama, sehingga mempermudah dalam pengembangan, pemeliharaan, dan pengujian kode.
Langkah 1 - Installasi Package
Dikarenakan kita akan menggunakan sweetAlert
dan package lain disini kita akan lakukan installasi terlebih dahulu, Silahkan jalankan perintah berikut ini di dalam terminal/CMD dan pastikan berada di dalam project Laravel-nya.
npm install clsx sweetalert2 @tabler/icons-react
Pada perintah diatas kita melakukan installasi 3
buah package diantaranya sebagai berikut :
Langkah 2 - Component Input
Kita lanjutkan untuk menambahkan Component Input
.
Silahkan Buat file baru dengan nama Input.jsx
di dalam folder resources/js/Components/
dan silahkan masukan kode berikut :
import React from 'react'
export default function Input({label, type, className, errors, ...props}) {
return (
<div className='flex flex-col gap-2'>
<label className='text-gray-600 text-sm'>
{label}
</label>
<input
type={type}
className={`w-full px-4 py-2 border text-sm rounded-md focus:outline-none focus:ring-0 bg-white text-gray-700 focus:border-gray-200 border-gray-200 ${className}`}
{...props}
/>
{errors && (
<small className='text-xs text-red-500'>{errors}</small>
)}
</div>
)
}
Pada kode diatas, pertama kita lakukan import React
terlebih dahulu.
import React from 'react'
Selanjutnya kita membuat sebuah React Functional Component dengan beberapa props diantara-nya label
, type
, className
, errors
dan ...props
.
export default function Input({label, type, className, errors, ...props})
Langkah 3 - Component Checkbox
Silahkan buka file resources/js/Components/Checkbox.jsx
, kemudian ubah kode-nya menjadi seperti berikut ini :
export default function Checkbox({ label, ...props }) {
return (
<div>
<div className="flex flex-row items-center gap-2">
<input
{...props}
type="checkbox"
className={
"rounded-md bg-white border-gray-200 checked:bg-teal-500"
}
/>
<label className="text-sm text-gray-700">{label}</label>
</div>
</div>
);
}
Di atas kita menambahkan props label.
Langkah 4 - Component Container
Kita lanjutkan untuk menambahkan Component Container
.
Silahkan Buat file baru dengan nama Container.jsx
di dalam folder resources/js/Components/
dan silahkan masukan kode berikut :
export default function Container({children}) {
return (
<div className="py-12">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
{children}
</div>
</div>
)
}
pada kode diatas kita membuat sebuah React Functional Component dengan props children
.
Langkah 5 - Component Textarea
Kita lanjutkan untuk menambahkan Component Textarea
.
Silahkan Buat file baru dengan nama Textarea.jsx
di dalam folder resources/js/Components/
dan silahkan masukan kode berikut :
export default function Textarea({label, className, errors,...props}) {
return (
<div className='flex flex-col gap-2'>
<label className='text-gray-600 dark:text-gray-500 text-sm'>
{label}
</label>
<textarea
className={`w-full px-4 py-2 border text-sm rounded-md focus:outline-none focus:ring-0 bg-white text-gray-700 focus:border-gray-200 border-gray-200 ${className}`}
{...props}
/>
{errors && (
<small className='text-xs text-red-500'>{errors}</small>
)}
</div>
)
}
pada kode diatas kita membuat sebuah React Functional Component dengan beberapa props label
,className
,errors
dan ``...props`.
Langkah 6 - Component Search
Kita lanjutkan untuk menambahkan Component Search
.
Silahkan Buat file baru dengan nama Search.jsx
di dalam folder resources/js/Components/
dan silahkan masukan kode berikut :
import { useForm } from '@inertiajs/react';
import { IconSearch } from '@tabler/icons-react';
import React from 'react'
export default function Search({url, placeholder}) {
// define use form inertia
const {data, setData, get} = useForm({
search : '',
})
// define method searchData
const handleSearchData = (e) => {
e.preventDefault();
get(`${url}?search=${data.search}`)
}
return (
<form onSubmit={handleSearchData}>
<div className='relative'>
<input
type='text'
value={data.search}
onChange={e => setData('search', e.target.value)}
className='py-2 px-4 pr-11 block w-full rounded-lg text-sm border focus:outline-none focus:ring-0 focus:ring-gray-400 text-gray-700 bg-white border-gray-200 focus:border-gray-200'
placeholder={placeholder}/>
<div className='absolute inset-y-0 right-0 flex items-center pointer-events-none pr-4'>
<IconSearch size={18} strokeWidth={1.5}/>
</div>
</div>
</form>
)
}
Pada kode diatas, pertama kita import semua yang kita butuhkan.
import { useForm } from '@inertiajs/react';
import { IconSearch } from '@tabler/icons-react';
import React from 'react'
Selanjutnya kita membuat sebuah React Functional Component dengan beberapa props url
dan placeholder
.
export default function Search({url, placeholder})
Didalam react function component, kita membuat sebuah state menggunakan form helper yang telah disediakan oleh inerita.
const {data, setData, get} = useForm({
search : '',
})
Kemudian kita juga membuat sebuah method baru dengan nama handleSearchData
, method ini kita gunakan untuk melakukan pencarian data, dan method ini dijalankan ketika form di submit.
// define method searchData
const handleSearchData = (e) => {
e.preventDefault();
get(`${url}?search=${data.search}`)
}
Langkah 7 - Component Card
Kita lanjutkan untuk menambahkan Component Card
.
Silahkan Buat file baru dengan nama Card.jsx
di dalam folder esources/js/Components/
dan silahkan masukan kode berikut :
import React from 'react'
export default function Card({ title, children, className }) {
return (
<>
<div className={`p-4 rounded-t-lg border ${className} bg-white`}>
<div className='flex items-center gap-2 font-semibold text-sm text-gray-700 capitalize'>
{title}
</div>
</div>
<div className='bg-white p-4 border border-t-0 border-b rounded-b-lg'>
{children}
</div>
</>
)
}
Langkah 8 - Component Table
Kita lanjutkan untuk menambahkan Component Table
.
Silahkan Buat file baru dengan nama Table.jsx
di dalam folder resources/js/Components/
dan silahkan masukan kode berikut :
import React from 'react'
const Card = ({ title, className, children }) => {
return (
<>
<div className={`p-4 rounded-t-lg border ${className} bg-white`}>
<div className='flex items-center gap-2 font-semibold text-sm text-gray-700 uppercase'>
{title}
</div>
</div>
<div className='bg-white rounded-b-lg border-t-0'>
{children}
</div>
</>
)
}
const Table = ({ children }) => {
return (
<div className="w-full overflow-hidden overflow-x-auto border-collapse rounded-b-lg border border-t-0">
<table className="w-full text-sm">
{children}
</table>
</div>
);
};
const Thead = ({ className, children }) => {
return (
<thead className={`${className} border-b bg-gray-50`}>{children}</thead>
);
};
const Tbody = ({ className, children }) => {
return (
<tbody className={`${className} divide-y bg-white`}>
{children}
</tbody>
);
};
const Td = ({ className, children}) => {
return (
<td
className={`${className} whitespace-nowrap p-4 align-middle text-gray-700`}
>
{children}
</td>
);
};
const Th = ({ className, children }) => {
return (
<th
scope="col"
className={`${className} h-12 px-4 text-left align-middle font-medium text-gray-700`}
>
{children}
</th>
);
};
const Empty = ({colSpan, message, children}) => {
return (
<tr>
<td colSpan={colSpan}>
<div className="flex items-center justify-center h-96">
<div className="text-center">
{children}
<div className="mt-5">
{message}
</div>
</div>
</div>
</td>
</tr>
)
}
Table.Card = Card;
Table.Thead = Thead;
Table.Tbody = Tbody;
Table.Td = Td;
Table.Th = Th;
Table.Empty = Empty;
export default Table;
Langkah 9 - Component Pagination
Kita lanjutkan untuk menambahkan Component Pagination
.
Silahkan Buat file baru dengan nama Pagination.jsx
di dalam folder resources/js/Components/
dan silahkan masukan kode berikut :
import React from 'react'
import { Link } from '@inertiajs/react';
import { IconChevronRight, IconChevronLeft } from '@tabler/icons-react';
export default function Pagination({ links }) {
const style = 'p-1 text-sm border rounded-md bg-white text-gray-500 hover:bg-gray-100'
return (
<>
<ul className="mt-2 lg:mt-5 justify-end flex items-center gap-1">
{links.map((item, i) => {
return item.url != null ? (
item.label.includes('Previous') ? (
<Link className={style} key={i} href={item.url}>
<IconChevronLeft size={'20'} strokeWidth={'1.5'}/>
</Link>
) : item.label.includes('Next') ? (
<Link className={style} key={i} href={item.url}>
<IconChevronRight size={'20'} strokeWidth={'1.5'}/>
</Link>
) : (
<Link className={`px-2 py-1 text-sm border rounded-md text-gray-500 hover:bg-gray-100 ${item.active ? 'bg-white text-gray-700' : 'bg-white'}`} key={i} href={item.url}>
{item.label}
</Link>
)
) : null;
})}
</ul>
</>
)
}
Pada kode diatas, pertama kita import semua yang kita butuhkan.
import React from 'react'
import { Link } from '@inertiajs/react';
import { IconChevronRight, IconChevronLeft } from '@tabler/icons-react';
Selanjutnya kita membuat sebuah React Functional Component dengan sebuah props links
.
export default function Pagination({ links })
Langkah 10 - Component Button
Kita lanjutkan untuk menambahkan Component Button
.
Silahkan Buat file baru dengan nama Button.jsx di dalam folder resources/js/Components/
dan silahkan masukan kode berikut :
import { Link, useForm } from '@inertiajs/react'
import { IconArrowBack, IconCheck, IconPencilCog, IconPlus, IconTrash } from '@tabler/icons-react';
import React from 'react'
import Swal from 'sweetalert2';
export default function Button({ type, url, className, children, ...props }) {
const { delete : destroy } = useForm();
const handleDeleteData = async (url) => {
Swal.fire({
title: 'Are you sure you want to delete this?',
text: 'Data is unrecoverable!',
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
confirmButtonText: 'Yes, delete it!',
cancelButtonText: 'Cancel'
}).then((result) => {
if (result.isConfirmed) {
destroy(url)
Swal.fire({
title: 'Success!',
text: 'Data deleted successfully!',
icon: 'success',
showConfirmButton: false,
timer: 1500
})
}
})
}
return (
<>
{type === 'add' &&
<Link href={url} className='px-4 py-2 text-sm border rounded-lg bg-white text-gray-700 flex items-center gap-2 hover:bg-gray-100'>
<IconPlus size={18} strokeWidth={1.5}/> <span className='hidden lg:flex'>Create New Data</span>
</Link>
}
{type === 'modal' &&
<button {...props} type='button' className={`${className} px-4 py-2 text-sm border rounded-lg flex items-center gap-2`}>
{children}
</button>
}
{type === 'submit' &&
<button type='submit' className='px-4 py-2 text-sm rounded-lg border border-teal-100 bg-teal-50 text-teal-500 flex items-center gap-2 hover:bg-teal-100'>
<IconCheck size={16} strokeWidth={1.5}/> Save Data
</button>
}
{type === 'cancel' &&
<Link href={url} className='px-4 py-2 text-sm rounded-lg border border-rose-100 bg-rose-50 text-rose-500 flex items-center gap-2 hover:bg-rose-100'>
<IconArrowBack size={16} strokeWidth={1.5}/> Go Back
</Link>
}
{type === 'edit' &&
<Link href={url} className='px-4 py-2 rounded-lg bg-orange-50 text-orange-500 flex items-center gap-2 hover:bg-orange-100'>
<IconPencilCog size={16} strokeWidth={1.5}/>
</Link>
}
{type === 'delete' &&
<button onClick={() => handleDeleteData(url)} className='px-4 py-2 rounded-lg bg-rose-50 text-rose-500 flex items-center gap-2 hover:bg-rose-100'>
<IconTrash size={18} strokeWidth={1.5}/>
</button>
}
</>
)
}
Pada kode diatas, pertama kita import semua yang kita butuhkan.
import { Link, useForm } from '@inertiajs/react'
import { IconArrowBack, IconCheck, IconPencilCog, IconPlus, IconTrash } from '@tabler/icons-react';
import React from 'react'
import Swal from 'sweetalert2';
Selanjutnya kita membuat sebuah React Functional Component dengan beberapa props type
,url
,className
,children
dan ...props
.
export default function Button({ type, url, className, children, ...props })
Didalam react function component, kita membuat sebuah state menggunakan form helper yang telah disediakan oleh inerita.
const { delete : destroy } = useForm();
Kemudian kita juga membuat sebuah method baru dengan nama handleDeleteData
dan method ini kita tambahkan sebuah paramater url
yang diambil dari props url
yang kita kirimkan.
const handleDeleteData = async (url) => {
Swal.fire({
title: 'Are you sure you want to delete this?',
text: 'Data is unrecoverable!',
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
confirmButtonText: 'Yes, delete it!',
cancelButtonText: 'Cancel'
}).then((result) => {
if (result.isConfirmed) {
destroy(url)
Swal.fire({
title: 'Success!',
text: 'Data deleted successfully!',
icon: 'success',
showConfirmButton: false,
timer: 1500
})
}
})
}
Didalam method tersebut kita menggunakan SweetAlert
untuk menampilkan jendela konfirmasi sebelum data benar-benar dihapus.
Swal.fire({
title: 'Are you sure you want to delete this?',
text: 'Data is unrecoverable!',
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
confirmButtonText: 'Yes, delete it!',
cancelButtonText: 'Cancel'
})
Sumber : membuat-reusable-component-dengan-react
kesimpulan
Pada artikel ini, kita telah belajar membuat Component Di React Js
Jika teman-teman ada kendala saat belajar, silahkan bisa bertanya melalui kolom komentar atau group Telegram SantriKoding.
Semoga bermanfaat! 😊