Skip to main content

Best Practice: File Style

Praktik Terbaik: Menyimpan File Style di Dekat Component​

Seiring berkembangnya aplikasi React, jumlah component dan aturan CSS akan semakin banyak. Jika seluruh style disimpan dalam satu file global seperti index.css, kode dapat menjadi sulit dikelola.

Salah satu praktik yang dapat digunakan adalah co-location, yaitu menyimpan file yang berkaitan dengan sebuah component di lokasi yang berdekatan.


1. Mengapa File CSS Perlu Dipisahkan?​

Pada project sederhana, kita mungkin hanya memiliki satu file:

src/
├── App.jsx
├── main.jsx
└── index.css

Semua style aplikasi kemudian ditulis di dalam index.css.

Pendekatan ini masih dapat digunakan untuk project kecil. Namun, ketika aplikasi semakin besar, file CSS dapat menjadi sangat panjang.

Masalah yang Dapat Muncul​

  • Sulit menemukan style untuk component tertentu.
  • File CSS menjadi terlalu besar.
  • Sulit mengetahui style mana yang digunakan oleh component tertentu.
  • Pemeliharaan kode menjadi lebih sulit.
  • Risiko konflik antar aturan CSS semakin besar.

Solusi​

Buat file CSS yang berkaitan dengan masing-masing component.

Contoh:

src/
└── components/
├── Header.jsx
├── Header.css
├── CoreConcept.jsx
└── CoreConcept.css

Dengan pendekatan ini, file yang berkaitan dengan component berada berdekatan.


2. Konsep Co-location​

Co-location adalah praktik menempatkan file-file yang saling berkaitan dalam lokasi yang berdekatan.

Misalnya:

Header.jsx
Header.css

Keduanya berkaitan dengan component Header.

Begitu juga:

CoreConcept.jsx
CoreConcept.css

Keduanya berkaitan dengan component CoreConcept.

Keuntungan utamanya adalah developer dapat dengan mudah menemukan kode JavaScript dan style yang digunakan oleh sebuah component.


3. Membuat File CSS untuk Component​

Misalnya kita memiliki component:

src/components/Header.jsx

Buat file CSS:

src/components/Header.css

Strukturnya menjadi:

src/
└── components/
├── Header.jsx
└── Header.css

Kemudian pindahkan style yang berkaitan dengan Header dari index.css ke Header.css.

Contoh:

header {
padding: 2rem;
text-align: center;
}

header h1 {
margin: 0;
}

4. Mengimpor CSS ke dalam Component​

Setelah membuat file CSS, import file tersebut langsung di dalam component.

import "./Header.css";

export default function Header() {
return (
<header>
<h1>React Essentials</h1>
</header>
);
}

Dengan cara ini, hubungan antara component dan file CSS terlihat dengan jelas.

Header.jsx
│
└── Header.css

5. Memindahkan Style dari index.css​

Misalnya sebelumnya semua style berada di:

src/index.css
header {
padding: 2rem;
text-align: center;
}

.core-concept {
padding: 1rem;
}

.button {
padding: 0.5rem 1rem;
}

Kita dapat memindahkan style tersebut ke file masing-masing.

Contohnya:

src/
└── components/
├── Header.jsx
├── Header.css
├── CoreConcept.jsx
└── CoreConcept.css

Header.css:

header {
padding: 2rem;
text-align: center;
}

CoreConcept.css:

.core-concept {
padding: 1rem;
}

6. CSS Import Tidak Otomatis Menjadi Scoped​

Hal penting yang harus dipahami adalah:

warning

Mengimpor file CSS di dalam component tidak berarti CSS tersebut hanya berlaku untuk component tersebut.

Misalnya Header.css berisi:

header {
background: red;
}

Kemudian di Header.jsx:

import "./Header.css";

Aturan:

header {
background: red;
}

tetap merupakan aturan CSS global.

Artinya, jika aplikasi memiliki component lain:

function App() {
return (
<div>
<Header />

<header>
<h2>Another Header</h2>
</header>
</div>
);
}

maka <header> lainnya juga dapat terkena aturan:

header {
background: red;
}

7. Mengapa CSS Tetap Global?​

Ketika menggunakan import CSS biasa:

import "./Header.css";

bundler seperti Vite akan memproses CSS tersebut dan memasukkannya ke dalam aplikasi.

CSS tersebut tetap mengikuti aturan CSS biasa.

Contohnya:

header {
color: white;
}

Selector header tidak mengetahui bahwa aturan tersebut berasal dari Header.jsx.

CSS hanya melihat elemen HTML yang cocok dengan selector tersebut.


8. Menggunakan Class untuk Mengurangi Konflik​

Salah satu cara sederhana untuk mengurangi konflik adalah menggunakan class yang lebih spesifik.

Daripada:

header {
background: red;
}

gunakan:

.header {
background: red;
}

Kemudian:

<header className="header">
<h1>React Essentials</h1>
</header>

Dengan cara ini, selector lebih spesifik terhadap component.

Namun, perlu diingat bahwa class CSS biasa tetap bersifat global.


9. CSS Modules​

Untuk kebutuhan yang lebih besar, React project dapat menggunakan pendekatan seperti CSS Modules.

Dengan CSS Modules, style dapat dibuat lebih terisolasi sehingga nama class tidak mudah bertabrakan dengan class dari component lain.

Contoh struktur:

Header/
├── Header.jsx
└── Header.module.css

Kemudian:

import styles from "./Header.module.css";

export default function Header() {
return (
<header className={styles.header}>
<h1>React Essentials</h1>
</header>
);
}

CSS:

.header {
background: red;
}

CSS Modules merupakan salah satu solusi ketika aplikasi membutuhkan style yang lebih terisolasi.


10. Struktur Folder Component​

Ketika jumlah component semakin banyak, kita dapat membuat subfolder untuk setiap component.

Struktur sederhana:

src/
└── components/
├── Header.jsx
├── Header.css
├── CoreConcept.jsx
└── CoreConcept.css

Struktur yang lebih terorganisasi:

src/
└── components/
├── Header/
│ ├── Header.jsx
│ └── Header.css
│
└── CoreConcept/
├── CoreConcept.jsx
└── CoreConcept.css

Dengan struktur tersebut, seluruh file yang berkaitan dengan satu component berada dalam satu folder.


11. Contoh Struktur Project​

Project React dapat memiliki struktur seperti berikut:

src/
├── assets/
│ ├── react-logo.png
│ └── react-core-concepts.png
│
├── components/
│ ├── Header/
│ │ ├── Header.jsx
│ │ └── Header.css
│ │
│ ├── CoreConcept/
│ │ ├── CoreConcept.jsx
│ │ └── CoreConcept.css
│ │
│ └── Button/
│ ├── Button.jsx
│ └── Button.css
│
├── App.jsx
├── main.jsx
└── index.css

Struktur ini membuat component dan style yang berkaitan menjadi lebih mudah ditemukan.


12. Contoh Header.jsx​

Jika menggunakan struktur:

src/components/Header/Header.jsx

maka component dapat ditulis:

import "./Header.css";

export default function Header() {
return (
<header className="header">
<h1>React Essentials</h1>
</header>
);
}

13. Contoh Header.css​

File:

src/components/Header/Header.css

dapat berisi:

.header {
padding: 2rem;
text-align: center;
}

.header h1 {
margin: 0;
}

14. Menyesuaikan Relative Path Asset​

Ketika component dipindahkan ke dalam subfolder, path untuk asset juga harus disesuaikan.

Misalnya struktur awal:

src/
├── assets/
│ └── react-logo.png
└── components/
└── Header.jsx

Maka dari Header.jsx:

import reactImg from "../assets/react-logo.png";

Namun jika struktur berubah menjadi:

src/
├── assets/
│ └── react-logo.png
│
└── components/
└── Header/
└── Header.jsx

Maka Header.jsx harus naik dua tingkat:

import reactImg from "../../assets/react-logo.png";

Alurnya:

Header.jsx
│
│ ../
▼
Header/
│
│ ../
▼
components/
│
▼
src/
│
▼
assets/

15. Menggunakan Component dari App.jsx​

Jika struktur project:

src/
├── App.jsx
└── components/
└── Header/
├── Header.jsx
└── Header.css

maka App.jsx dapat mengimpor component:

import Header from "./components/Header/Header.jsx";

export default function App() {
return (
<div>
<Header />
</div>
);
}

16. Keuntungan Struktur Component dan Style yang Berdekatan​

Pendekatan ini memberikan beberapa keuntungan.

Lebih Mudah Dicari​

Developer dapat menemukan component dan CSS-nya dalam folder yang sama.

Header/
├── Header.jsx
└── Header.css

Lebih Mudah Dipelihara​

Jika ingin mengubah tampilan Header, kita cukup membuka folder Header.

Lebih Modular​

Setiap component memiliki kumpulan file yang berkaitan.

Lebih Mudah Dipindahkan​

Component dapat dipindahkan bersama file CSS-nya.

Mengurangi File Global​

index.css tidak perlu menampung seluruh style aplikasi.


17. Apa yang Tetap Cocok di index.css?​

Walaupun style component dapat dipisahkan, bukan berarti index.css harus dihilangkan sepenuhnya.

Style yang bersifat global masih cocok ditempatkan di sana.

Contohnya:

* {
box-sizing: border-box;
}

body {
margin: 0;
font-family: Arial, sans-serif;
}

html {
background: #f5f5f5;
}

Jadi, pembagian sederhananya:

index.css
│
└── Global styles

Component.css
│
└── Component-specific styles

18. Alur Kerja yang Direkomendasikan​

Ketika membuat component baru:

Buat Component
│
▼
Buat File CSS
│
▼
Simpan Berdekatan
│
▼
Import CSS ke Component
│
▼
Pindahkan Style yang Relevan
│
▼
Periksa Relative Path
│
▼
Uji Tampilan

19. Contoh Struktur Akhir​

Struktur project yang lebih terorganisasi:

src/
├── assets/
│ ├── react-logo.png
│ └── react-core-concepts.png
│
├── components/
│ ├── Header/
│ │ ├── Header.jsx
│ │ └── Header.css
│ │
│ ├── CoreConcept/
│ │ ├── CoreConcept.jsx
│ │ └── CoreConcept.css
│ │
│ └── Button/
│ ├── Button.jsx
│ └── Button.css
│
├── App.jsx
├── main.jsx
└── index.css

Struktur tersebut menerapkan prinsip co-location, yaitu menempatkan file yang saling berkaitan dalam lokasi yang berdekatan.


20. Poin Penting​

Beberapa hal yang perlu diingat:

  • Component dapat memiliki file CSS sendiri.
  • File CSS sebaiknya disimpan dekat dengan component yang menggunakannya.
  • Import CSS dapat dilakukan langsung di file .jsx.
  • CSS biasa tetap bersifat global meskipun di-import dari component.
  • Gunakan class yang spesifik untuk mengurangi kemungkinan konflik.
  • CSS Modules dapat digunakan jika membutuhkan style yang lebih terisolasi.
  • index.css tetap cocok untuk style yang benar-benar bersifat global.
  • Jika component dipindahkan ke subfolder, relative path asset harus disesuaikan.
  • Struktur folder sebaiknya dibuat konsisten di seluruh project.

Kesimpulan​

Menyimpan file CSS di dekat component merupakan salah satu praktik yang membantu membuat project React lebih terorganisasi.

Contoh sederhana:

Header/
├── Header.jsx
└── Header.css

Kemudian CSS diimpor langsung:

import "./Header.css";

Untuk project yang lebih besar, struktur ini dapat dikembangkan menjadi:

src/
├── components/
│ ├── Header/
│ │ ├── Header.jsx
│ │ └── Header.css
│ │
│ └── CoreConcept/
│ ├── CoreConcept.jsx
│ └── CoreConcept.css
│
├── App.jsx
├── main.jsx
└── index.css

Dengan pendekatan co-location, component, style, dan file pendukungnya lebih mudah ditemukan, dipahami, dan dipelihara.