CSS Styling & Dynamic Styling
Dalam React, CSS dapat digunakan untuk mengatur tampilan component seperti halnya pada HTML biasa.
Namun, React juga memungkinkan kita mengubah class CSS secara dinamis berdasarkan kondisi tertentu, misalnya State.
Contoh yang sering digunakan adalah memberikan class active pada tombol tab yang sedang dipilih.
1. class vs className
Pada HTML biasa, class CSS ditulis menggunakan atribut:
<button class="active">Components</button>
Sedangkan pada JSX, gunakan:
<button className="active">Components</button>
Jadi, dalam React:
className
digunakan sebagai pengganti:
class
Contoh
<button className="active">
Components
</button>
2. Mengapa JSX Menggunakan className?
JSX menggunakan sintaks yang dekat dengan JavaScript.
Kata class memiliki makna khusus dalam JavaScript karena digunakan untuk mendefinisikan class.
Karena itu, React menggunakan:
className
untuk menentukan class CSS pada elemen.
Contoh:
<div className="container">
<h1>Hello React</h1>
</div>
3. Apa Itu Dynamic Styling?
Dynamic Styling adalah teknik mengubah tampilan component berdasarkan kondisi tertentu.
Misalnya sebuah aplikasi memiliki beberapa tombol:
Components
JSX
Props
State
Ketika pengguna memilih:
Components
kita ingin tombol tersebut mendapatkan class:
active
Sehingga CSS dapat memberikan tampilan berbeda, misalnya:
.active {
background-color: blue;
color: white;
}
Ketika pengguna memilih tab lain, class active berpindah ke tombol tersebut.
4. Menggunakan State sebagai Dasar Dynamic Styling
Misalnya kita menyimpan tab yang sedang dipilih menggunakan State:
const [selectedTopic, setSelectedTopic] =
useState("components");
State tersebut berisi:
components
Artinya tab components sedang aktif.
5. Membandingkan State dengan Identifier Tab
Untuk mengetahui apakah sebuah tombol sedang aktif, kita dapat membandingkan:
selectedTopic === "components"
Hasilnya adalah nilai Boolean:
true
atau:
false
Contohnya:
<TabButton
isSelected={selectedTopic === "components"}
>
Components
</TabButton>
Jika:
selectedTopic = "components"
maka:
selectedTopic === "components"
menghasilkan:
true
6. Mengirim isSelected sebagai Props
Nilai hasil perbandingan tersebut dapat dikirim ke component TabButton melalui prop:
isSelected={selectedTopic === "components"}
Contoh lengkap:
<TabButton
isSelected={selectedTopic === "components"}
onSelect={() => handleSelect("components")}
>
Components
</TabButton>
Untuk JSX:
<TabButton
isSelected={selectedTopic === "jsx"}
onSelect={() => handleSelect("jsx")}
>
JSX
</TabButton>
Dengan demikian, setiap tombol mengetahui apakah dirinya sedang dipilih.
7. Menerima Prop isSelected
Di component TabButton, kita dapat menerima prop tersebut menggunakan destructuring:
export default function TabButton({
children,
onSelect,
isSelected,
}) {
// ...
}
Sekarang component memiliki tiga data:
children
onSelect
isSelected
isSelected berisi:
true
atau:
false
8. Menggunakan Ternary untuk className
Kita dapat menggunakan ternary operator untuk menentukan nilai className:
className={isSelected ? "active" : undefined}
Artinya:
isSelected = true
↓
className = "active"
Sedangkan:
isSelected = false
↓
className = undefined
9. Contoh TabButton.jsx
export default function TabButton({
children,
onSelect,
isSelected,
}) {
return (
<li>
<button
className={isSelected ? "active" : undefined}
onClick={onSelect}
>
{children}
</button>
</li>
);
}
Ketika isSelected bernilai true, hasil HTML yang dihasilkan React secara konsep akan memiliki:
<button class="active">
Components
</button>
Jika isSelected bernilai false, tidak ada class active yang ditambahkan.
10. Menggunakan CSS
Misalnya kita memiliki file CSS:
.active {
background-color: #2563eb;
color: white;
}
Ketika tombol aktif:
<button class="active">
Components
</button>
CSS tersebut akan diterapkan.
Ketika tombol tidak aktif:
<button>
JSX
</button>
class active tidak digunakan.
11. Contoh App.jsx Lengkap
Berikut contoh sederhana implementasi dynamic styling:
import { useState } from "react";
import TabButton from "./components/TabButton.jsx";
function App() {
const [selectedTopic, setSelectedTopic] =
useState("components");
function handleSelect(selectedButton) {
setSelectedTopic(selectedButton);
}
return (
<main>
<menu>
<TabButton
isSelected={selectedTopic === "components"}
onSelect={() => handleSelect("components")}
>
Components
</TabButton>
<TabButton
isSelected={selectedTopic === "jsx"}
onSelect={() => handleSelect("jsx")}
>
JSX
</TabButton>
<TabButton
isSelected={selectedTopic === "props"}
onSelect={() => handleSelect("props")}
>
Props
</TabButton>
<TabButton
isSelected={selectedTopic === "state"}
onSelect={() => handleSelect("state")}
>
State
</TabButton>
</menu>
</main>
);
}
export default App;
12. Alur Dynamic Styling
Ketika aplikasi pertama kali dijalankan:
selectedTopic = "components"
Kemudian React mengevaluasi:
selectedTopic === "components"
Hasilnya:
true
Maka:
isSelected={true}
dikirim ke TabButton.
Kemudian:
className={isSelected ? "active" : undefined}
menghasilkan:
className="active"
13. Ketika Pengguna Memilih Tab Lain
Misalnya pengguna memilih JSX:
handleSelect("jsx");
State berubah:
selectedTopic = "jsx"
React kemudian melakukan re-render.
Pada render berikutnya:
selectedTopic === "components"
menghasilkan:
false
Sedangkan:
selectedTopic === "jsx"
menghasilkan:
true
Akibatnya class active berpindah dari tombol Components ke tombol JSX.
14. Alur Lengkap
Prosesnya dapat digambarkan seperti berikut:
User klik tombol JSX
↓
handleSelect("jsx")
↓
setSelectedTopic("jsx")
↓
State berubah
↓
React melakukan re-render
↓
selectedTopic === "jsx"
↓
isSelected = true
↓
className = "active"
↓
CSS .active diterapkan
15. Dynamic Styling dengan Ternary
Pola yang digunakan adalah:
className={condition ? "active" : undefined}
Contoh lain:
<div
className={isActive ? "active" : undefined}
>
Content
</div>
Jika isActive bernilai true:
<div class="active">
Content
</div>
Jika isActive bernilai false:
<div>
Content
</div>
16. Dynamic Styling dengan &&
Untuk kondisi sederhana, kita juga dapat menggunakan operator &&:
className={isSelected && "active"}
Namun, penggunaan ternary:
className={isSelected ? "active" : undefined}
sering lebih eksplisit karena kita secara jelas menentukan nilai ketika kondisi benar dan ketika kondisi salah.
17. Dynamic Styling dan Props
Contoh ini menunjukkan hubungan antara State, Props, dan CSS:
State
↓
Perbandingan
↓
Boolean
↓
Props
↓
className
↓
CSS
Contohnya:
isSelected={selectedTopic === "components"}
Kemudian di child:
className={isSelected ? "active" : undefined}
18. Mengapa Dynamic Styling Sebaiknya Dikelola dari Parent?
Pada contoh tab, App memiliki informasi tentang:
selectedTopic
Karena itu, App mengetahui tab mana yang sedang aktif.
TabButton tidak perlu mengetahui seluruh State tersebut.
TabButton cukup menerima informasi:
isSelected
Dengan demikian terjadi pemisahan tanggung jawab:
App
├── Mengelola State
├── Menentukan tab aktif
└── Mengirim isSelected
TabButton
└── Menampilkan tampilan berdasarkan isSelected
Pendekatan ini membuat component lebih reusable.
19. Poin Penting
Beberapa hal yang perlu diingat:
- Gunakan
className, bukanclass, di JSX. - Dynamic styling dapat dibuat berdasarkan State atau Props.
- Nilai Boolean dapat digunakan untuk menentukan class CSS.
- Parent component dapat menentukan apakah sebuah child sedang aktif.
- Informasi tersebut dapat dikirim melalui prop seperti
isSelected. - Child component dapat menggunakan
isSelecteduntuk menentukanclassName. - Perubahan State menyebabkan React melakukan re-render.
- Setelah re-render, class CSS dapat berubah secara otomatis.
Kesimpulan
Dynamic Styling memungkinkan tampilan component berubah berdasarkan kondisi aplikasi.
Dalam contoh tab, State:
const [selectedTopic, setSelectedTopic] =
useState("components");
digunakan untuk menentukan tombol yang aktif:
isSelected={selectedTopic === "components"}
Kemudian TabButton menggunakan nilai tersebut:
className={isSelected ? "active" : undefined}
Sehingga perubahan State secara otomatis memengaruhi class CSS:
State berubah
↓
React re-render
↓
isSelected diperbarui
↓
className diperbarui
↓
CSS berubah
↓
Tampilan UI berubah
Konsep ini sangat penting dalam React karena banyak komponen membutuhkan tampilan yang berubah berdasarkan State atau Props, seperti tab aktif, menu navigasi, tombol terpilih, modal, form, dan berbagai elemen interaktif lainnya.