Membangun Komponen React yang Dapat Digunakan Kembali Menggunakan Tailwind
Diterbitkan: 2022-03-10Dalam posting ini, kita akan melihat beberapa cara berbeda untuk membangun komponen React yang dapat digunakan kembali yang memanfaatkan Tailwind di bawah tenda sambil mengekspos antarmuka yang bagus ke komponen lain. Ini akan meningkatkan kode Anda dengan berpindah dari daftar panjang nama kelas ke alat peraga semantik yang lebih mudah dibaca dan dipelihara.
Anda harus bekerja dengan React untuk mendapatkan pemahaman yang baik tentang posting ini.
Tailwind adalah kerangka kerja CSS yang sangat populer yang menyediakan kelas utilitas tingkat rendah untuk membantu pengembang membuat desain khusus. Ini semakin populer selama beberapa tahun terakhir karena memecahkan dua masalah dengan sangat baik:
- Tailwind memudahkan untuk membuat perubahan berulang pada HTML tanpa menggali melalui stylesheet untuk menemukan pemilih CSS yang cocok.
- Tailwind memiliki konvensi dan default yang waras. Ini memudahkan orang untuk memulai tanpa menulis CSS dari awal.
Tambahkan dokumentasi yang komprehensif dan tidak mengherankan mengapa Tailwind begitu populer.
Metode ini akan membantu Anda mengubah kode yang terlihat seperti ini:
<button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"> Enable </button>
Untuk kode yang terlihat seperti ini:
<Button size="sm" textColor="white" bgColor="blue-500"> Enable </Button>
Perbedaan antara kedua cuplikan tersebut adalah pada cuplikan pertama kami menggunakan tag tombol HTML standar, sedangkan cuplikan kedua menggunakan komponen <Button>
. Komponen <Button>
telah dibuat agar dapat digunakan kembali dan lebih mudah dibaca karena memiliki semantik yang lebih baik. Alih-alih daftar panjang nama kelas, ia menggunakan properti untuk mengatur berbagai atribut seperti size
, textColor
, dan bgColor
.
Mari kita mulai.
Metode 1: Mengontrol Kelas Dengan Modul Nama Kelas
Cara sederhana untuk mengadaptasi Tailwind ke dalam aplikasi React adalah dengan memasukkan nama kelas dan mengaktifkannya secara terprogram.
Modul classnames npm memudahkan untuk beralih kelas di React. Untuk mendemonstrasikan bagaimana Anda dapat menggunakan ini, mari kita ambil kasus penggunaan di mana Anda memiliki komponen <Button>
di aplikasi React Anda.
// This could be hard to read. <button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">Enable</button> // This is more conventional React. <Button size="sm" textColor="white" bgColor="blue-500">Enable</Button>
Mari kita lihat bagaimana memisahkan kelas Tailwind sehingga orang yang menggunakan komponen <Button>
ini dapat menggunakan props React seperti size
, textColor
, dan bgColor
.
- Teruskan props seperti
bgColor
dantextColor
langsung ke dalam template string nama kelas. - Gunakan objek untuk mengganti nama kelas secara terprogram (seperti yang telah kita lakukan dengan prop
size
)
Dalam contoh kode di bawah ini, kita akan melihat kedua pendekatan tersebut.
// Button.jsx import classnames from 'classnames'; function Button ({size, bgColor, textColor, children}) { return ( <button className={classnames("bg-${bgColor} text-${textColor} font-bold py-2 px-4 rounded", { "text-xs": size === 'sm' "text-xl": size === 'lg', })}> {children} </button> ) }; export default Button;
Pada kode di atas, kita mendefinisikan komponen Button
yang mengambil props berikut:
-
size
Menentukan ukuran tombol dan menerapkan kelas Tailwindtext-xs
atautext-xl
-
bgColor
Mendefinisikan warna latar belakang tombol dan menerapkan kelas Tailwindbg-*
. -
textColor
Mendefinisikan warna teks tombol dan menerapkan kelas Tailwindtext-* classes
. -
children
Setiap subkomponen akan dilewatkan di sini. Biasanya akan berisi teks di dalam<Button>
.
Dengan mendefinisikan Button.jsx
, kita sekarang dapat mengimpornya dan menggunakan props React sebagai ganti nama kelas. Ini membuat kode kita lebih mudah dibaca dan digunakan kembali.
import Button from './Button'; <Button size="sm" textColor="white" bgColor="blue-500">Enable</Button>
Menggunakan Nama Kelas Untuk Komponen Interaktif
Tombol adalah kasus penggunaan yang sangat sederhana. Bagaimana dengan sesuatu yang lebih rumit? Nah, Anda dapat mengambil ini lebih jauh untuk membuat komponen interaktif.
Sebagai contoh, mari kita lihat dropdown yang dibuat menggunakan Tailwind.
Dropdown interaktif yang dibuat menggunakan Tailwind dan pengalihan nama kelas.
Untuk contoh ini, kami membuat komponen HTML menggunakan nama kelas Tailwind CSS tetapi kami mengekspos komponen React yang terlihat seperti ini:
<Dropdown options={\["Edit", "Duplicate", "Archive", "Move", "Delete"\]} onOptionSelect={(option) => { console.log("Selected Option", option)} } />
Melihat kode di atas, Anda akan melihat bahwa kami tidak memiliki kelas Tailwind. Semuanya tersembunyi di dalam kode implementasi <Dropdown/>
. Pengguna komponen Dropdown
ini hanya perlu memberikan daftar options
dan penangan klik, onOptionSelect
ketika option
diklik.
Mari kita lihat bagaimana komponen ini dapat dibangun menggunakan Tailwind.
Menghapus beberapa kode yang tidak terkait, inilah inti logikanya. Anda dapat melihat Codepen ini untuk contoh lengkapnya.
import classNames from 'classnames'; function Dropdown({ options, onOptionSelect }) { // Keep track of whether the dropdown is open or not. const [isActive, setActive] = useState(false); const buttonClasses = `inline-flex justify-center w-full rounded-md border border-gray-300 px-4 py-2 bg-white text-sm leading-5 font-medium text-gray-700 hover:text-gray-500 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-blue-500 active:text-gray-200 transition ease-in-out duration-150`; return ( // Toggle the dropdown if the button is clicked <button onClick={() => setActive(!isActive)} className={buttonClasses}> Options </button> // Use the classnames module to toggle the Tailwind .block and .hidden classes <div class={classNames("origin-top-right absolute right-0 mt-2 w-56 rounded-md shadow-lg", { block: isActive, hidden: !isActive })}> // List items are rendered here. {options.map((option) => <div key={option} onClick={(e) => onOptionSelect(option)}>{option}</div>)} </div> ) } export default Dropdown;
Dropdown dibuat interaktif dengan menampilkan atau menyembunyikannya secara selektif menggunakan kelas .hidden
dan .block
. Setiap kali <button>
ditekan, kami mengaktifkan handler onClick
yang mengubah status isActive
. Jika tombol aktif ( isActive === true
), kami mengatur kelas block
. Jika tidak, kami mengatur kelas hidden
. Ini adalah kedua kelas Tailwind untuk mengubah perilaku tampilan.
Singkatnya, modul classnames adalah cara sederhana dan efektif untuk mengontrol nama class untuk Tailwind secara terprogram. Itu membuatnya lebih mudah untuk memisahkan logika ke dalam props React, yang membuat komponen Anda lebih mudah untuk digunakan kembali. Ia bekerja untuk komponen sederhana dan interaktif.
Metode 2: Menggunakan Konstanta Untuk Mendefinisikan Sistem Desain
Cara lain untuk menggunakan Tailwind dan React bersama-sama adalah dengan menggunakan konstanta dan properti pemetaan ke konstanta tertentu. Ini efektif untuk membangun sistem desain. Mari kita tunjukkan dengan sebuah contoh.
Mulailah dengan file theme.js
tempat Anda mencantumkan sistem desain Anda.
// theme.js (you can call it whatever you want) export const ButtonType = { primary: "bg-blue-500 hover:bg-blue-700 text-white font-bold rounded", secondary: "bg-blue-500 hover:bg-blue-700 text-white font-bold rounded", basic: "bg-white hover:bg-gray-700 text-gray-700 font-bold rounded", delete: "bg-red-300 hover:bg-red-500 text-white font-bold rounded" }; export const ButtonSize = { sm: "py-2 px-4 text-xs", lg: "py-3 px-6 text-lg" }
Dalam hal ini, kami memiliki dua set konstanta:
-
ButtonType
mendefinisikan bagaimana tombol ditata di aplikasi kita. -
ButtonSizes
mendefinisikan ukuran tombol di aplikasi kita.
Sekarang, mari kita tulis komponen <Button>
kita:
import {ButtonType, ButtonSize} from './theme'; function Button({size, type, children}) { // This can be improved. I'm keeping it simple here by joining two strings. const classNames = ButtonType[type] + " " + ButtonSize[size]; return ( <button className={classNames}>{children}</button> ) } export default Button;
Kami menggunakan ButtonType
dan ButtonSize
untuk membuat daftar nama kelas. Ini membuat antarmuka <Button>
kami jauh lebih bagus. Ini memungkinkan kita menggunakan alat peraga size
dan type
alih-alih meletakkan semuanya dalam string nama kelas.
// Cleaner and well defined props. <Button size="xs" type="primary">Enable</Button>
Dibandingkan dengan pendekatan sebelumnya:
// Exposing class names <button className="py-2 px-4 text-xs bg-blue-500 hover:bg-blue-700 text-white font-bold rounded">Enable</button>
Jika Anda perlu mendefinisikan ulang tampilan tombol di aplikasi Anda, cukup edit file theme.js
dan semua tombol di aplikasi Anda akan diperbarui secara otomatis. Ini bisa lebih mudah daripada mencari nama kelas di berbagai komponen.
Metode 3: Menyusun Utilitas Dengan @apply
Cara ketiga untuk meningkatkan keterbacaan komponen React Anda menggunakan CSS dan pola @apply
yang tersedia di PostCSS untuk mengekstrak kelas berulang. Pola ini melibatkan penggunaan stylesheet dan post-processors.
Mari kita tunjukkan cara kerjanya melalui sebuah contoh. Misalkan Anda memiliki grup Tombol yang memiliki Tombol Utama dan Sekunder.
<button className="py-2 px-4 mr-4 text-xs bg-blue-500 hover:bg-blue-700 text-white font-bold rounded">Update Now</button> <button className="py-2 px-4 text-xs mr-4 hover:bg-gray-100 text-gray-700 border-gray-300 border font-bold rounded">Later</button>
Menggunakan pola @apply
, Anda dapat menulis HTML ini sebagai:
<button className="btn btn-primary btn-xs">Update Now</button> <button className="btn btn-secondary btn-xs">Later</button>
Yang kemudian dapat diadopsi ke React menjadi:
import classnames from "classnames"; function Button ({size, type, children}) { const bSize = "btn-" + size; const bType = "btn-" + type; return ( <button className={classnames("btn", bSize, bType)}>{children}</button> ) } Button.propTypes = { size: PropTypes.oneOf(['xs, xl']), type: PropTypes.oneOf(['primary', 'secondary']) }; // Using the Button component. <Button type="primary" size="xs">Update Now</Button> <Button type="secondary" size="xs">Later</Button>
Inilah cara Anda membuat nama kelas bergaya BEM ini seperti .btn
, .btn-primary
, dan lainnya. Mulailah dengan membuat file button.css
:
/\* button.css \*/ @tailwind base; @tailwind components; .btn { @apply py-2 px-4 mr-4 font-bold rounded; } .btn-primary { @apply bg-blue-500 hover:bg-blue-700 text-white; } .btn-secondary { @apply hover:bg-gray-700 text-gray-700 border-gray-300 border; } .btn-xs { @apply text-xs; } .btn-xl { @apply text-xl; } @tailwind utilities;
Kode di atas bukan CSS asli tetapi akan dikompilasi oleh PostCSS. Ada repositori GitHub yang tersedia di sini yang menunjukkan cara menyiapkan PostCSS dan Tailwind untuk proyek JavaScript.
Ada juga video pendek yang menunjukkan cara mengaturnya di sini.
Kekurangan Menggunakan @apply
Konsep mengekstrak kelas utilitas Tailwind ke kelas CSS tingkat yang lebih tinggi sepertinya masuk akal, tetapi memiliki beberapa kelemahan yang harus Anda waspadai. Mari kita soroti ini dengan contoh lain.
Pertama, dengan mengekstrak nama kelas ini, kami kehilangan beberapa informasi. Misalnya, kita perlu menyadari bahwa .btn-primary
harus ditambahkan ke komponen yang sudah memiliki .btn
yang diterapkan padanya. Selain itu, .btn-primary
dan .btn-secondary
tidak dapat diterapkan bersama-sama. Informasi ini tidak terbukti hanya dengan melihat kelas.
Jika komponen ini adalah sesuatu yang lebih rumit, Anda juga perlu memahami hubungan induk-anak antara kelas. Di satu sisi, inilah masalah yang dirancang Tailwind untuk dipecahkan, dan dengan menggunakan @apply
, kami mengembalikan masalah tersebut, dengan cara yang berbeda.
Berikut adalah video di mana Adam Wathan — pencipta Tailwind — menyelami pro dan kontra menggunakan @apply
.
Ringkasan
Dalam artikel ini, kami melihat tiga cara Anda dapat mengintegrasikan Tailwind ke dalam aplikasi React untuk membangun komponen yang dapat digunakan kembali. Metode ini membantu Anda membangun komponen React yang memiliki antarmuka lebih bersih menggunakan props
.
- Gunakan modul nama kelas untuk beralih kelas secara terprogram.
- Tentukan file konstanta tempat Anda menentukan daftar kelas per status komponen.
- Gunakan
@apply
untuk mengekstrak kelas CSS tingkat tinggi.
Jika Anda memiliki pertanyaan, kirimkan saya pesan di Twitter di @tilomitra.
Bacaan yang Direkomendasikan di SmashingMag:
- Menyiapkan Tailwind CSS Dalam Proyek Bereaksi
- Membuat Tabel yang Dapat Diurutkan Dengan React
- Panduan Untuk DevTools CSS Baru Dan Eksperimental Di Firefox
- Buat Panel Konten Ekspansi Dan Kontrak Anda Sendiri