Bikin Komponen di ReactJS? Gampang Kalau Kamu Tau Caranya
Membangun antarmuka pengguna (UI) yang kompleks tapi tetap teratur dan mudah dikelola itu bisa jadi tantangan, apalagi kalau aplikasinya makin gede. Nah, ReactJS muncul sebagai salah satu solusi keren buat masalah ini. Kunci utamanya ada di konsep yang namanya komponen.
Kalau diibaratkan, bikin aplikasi pakai React itu kayak main LEGO. Setiap balok LEGO itu adalah komponen. Kamu bisa punya balok kecil (komponen sederhana) kayak tombol, input field, atau sepotong teks. Terus, balok-balok kecil ini bisa kamu gabungin jadi balok yang lebih besar (komponen kompleks) kayak kartu produk, form login, atau bahkan seluruh halaman. Nah, serunya, balok yang udah kamu bikin bisa dipake lagi di tempat lain tanpa perlu bikin dari awal. Hemat waktu, kan?
Intinya, komponen itu adalah unit UI yang independen, bisa dipakai ulang (reusable), dan punya logika serta tampilannya sendiri. Dia yang bakal nentuin apa yang kelihatan di layar dan gimana reaksinya kalau ada interaksi dari user.
Di artikel ini, kita bakal ngulik tuntas gimana caranya bikin komponen di React. Jangan khawatir, gaya bahasanya santai aja biar gampang dicerna, apalagi buat kamu yang mungkin baru kenal React atau pengen nyegerin ilmu. Kita fokus ke cara-cara yang paling umum dan up-to-date di dunia React sekarang. Siap? Let's go!
Komponen Fungsional vs. Komponen Kelas: Pilih Mana?
Dulu banget, komponen di React itu ada dua jenis utama: Komponen Kelas (Class Components) dan Komponen Fungsional (Functional Components). Komponen Kelas identik sama yang namanya state
(data internal komponen) dan lifecycle methods (fungsi yang jalan di momen-momen tertentu komponen, kayak saat pertama muncul atau saat diupdate).
Contoh Komponen Kelas (Sekadar tahu aja, sekarang jarang dipakai untuk yang baru):
javascript
import React, { Component } from 'react';class MyButton extends Component {
render() {
return {this.props.text};
}
}
Nah, semenjak React punya yang namanya Hooks (mulai versi 16.8), cara bikin komponen jadi makin asyik dan simpel. Komponen Fungsional yang tadinya cuma bisa buat nampilin sesuatu (disebut stateless atau presentational component), sekarang juga bisa punya state dan ngelakuin side effects (kayak ngambil data dari API). Ini semua berkat Hooks kayak useState
dan useEffect
.
Karena Hooks bikin Komponen Fungsional jauh lebih kuat, ringkas, dan mudah dipahami, mayoritas pengembang React sekarang lebih suka pakai Komponen Fungsional. Jadi, di artikel ini, kita bakal fokus banget ke cara bikin komponen pakai Komponen Fungsional dan Hooks.
Langkah Pertama: Bikin Komponen Fungsional Paling Simpel
Oke, kita mulai dari yang paling basic. Komponen fungsional itu sebenarnya cuma fungsi JavaScript biasa yang me-return JSX (JavaScript XML). JSX itu sintaks ekstensi buat nulis HTML di dalam JavaScript.
Biasanya, satu komponen ditaruh dalam satu file JavaScript sendiri. Nama filenya disamain sama nama komponennya, diawali huruf kapital (ini konvensi yang penting!).
Contoh: Bikin komponen SelamatDatang.js
javascript
// src/components/SelamatDatang.jsimport React from 'react'; // Wajib diimport kalau pakai JSX// Ini dia komponen fungsionalnya
function SelamatDatang() {
return (
{/ JSX harus dibungkus dalam satu elemen root /}
Halo Dunia!
Selamat datang di aplikasi React pertamaku (atau kesekian kalinya)!
);
}
Penjelasan:
import React from 'react';
: Ini penting karena JSX yang kita tulis nanti akan ditranspilasi (diubah) jadi pemanggilan fungsiReact.createElement()
.function SelamatDatang() { ... }
: Ini fungsi JavaScript biasa. Nama fungsinya pakePascalCase
(huruf pertama kapital).return ( ... );
: Fungsi ini me-return JSX. Ingat, JSX harus dibungkus dalam satu elemen root. Bisadiv
,span
, atau pakai Fragment (<>...
) kalau nggak mau nambah elemen HTML.export default SelamatDatang;
: Ini buat ngebolehin komponenSelamatDatang
dipake di file lain pakeimport
.
Cara Pakai Komponennya
Setelah dibikin dan diekspor, komponen SelamatDatang
bisa kamu panggil di komponen lain, misalnya di App.js
(yang biasanya jadi komponen utama aplikasi React).
javascript
// src/App.jsimport React from 'react';
import SelamatDatang from './components/SelamatDatang'; // Import komponennyafunction App() {
return (
{/ Panggil komponen SelamatDatang seperti tag HTML biasa /}
Ini teks dari komponen App.
{/ Bisa dipanggil berkali-kali kalau perlu /}
{/ /}
);
}
Voila! Sekarang di browser kamu bakal lihat teks "Halo Dunia!" dan paragraf di bawahnya, yang berasal dari komponen SelamatDatang
yang kamu panggil di dalam komponen App
. Gampang, kan?
Makin Asyik Pakai Props: Data Antar Komponen
Komponen yang cuma nampilin konten statis (kayak contoh SelamatDatang
tadi) itu kurang fleksibel. Gimana kalau kita pengen bikin komponen Tombol
yang teksnya bisa beda-beda? Di sinilah peran props (singkatan dari properties) datang.
Props itu kayak argumen yang kamu kasih ke sebuah fungsi, tapi ini dikasih ke komponen. Dia bentuknya objek yang isinya data-data yang dikirim dari komponen "induk" (parent) ke komponen "anak" (child). Props sifatnya read-only di dalam komponen anak, artinya nggak bisa diubah dari komponen anak itu sendiri.
Cara ngasih props ke komponen anak itu kayak ngasih atribut di tag HTML:
javascript
// Di komponen induk (misal, App.js)import React from 'react';
import Tombol from './components/Tombol';function App() {
return (
{/ Ngasih props 'teks' dan 'warna' /}
);
}
Nah, di komponen Tombol.js
, kamu bisa nerima props itu sebagai argumen pertama dari fungsi komponennya:
javascript
// src/components/Tombol.jsimport React from 'react';// Komponen menerima objek 'props' sebagai argumen
function Tombol(props) {
// props akan berisi { teks: "...", warna: "..." }
const styleTombol = {
backgroundColor: props.warna === 'biru' ? 'blue' : 'red',
color: 'white',
padding: '10px',
margin: '5px',
border: 'none',
borderRadius: '5px',
cursor: 'pointer'
};return (
{props.teks} {/ Menggunakan nilai dari props /}
);
}
Destructuring Props Biar Lebih Rapi
Mengakses props pakai props.namaProp
itu sedikit repetitif. Ada cara yang lebih rapi pakai destructuring. Jadi, alih-alih menerima props
sebagai objek utuh, kita langsung ambil properti yang kita butuhkan:
javascript
// src/components/Tombol.js (Pakai Destructuring)import React from 'react';// Langsung ambil 'teks' dan 'warna' dari objek props
function Tombol({ teks, warna }) {
const styleTombol = {
backgroundColor: warna === 'biru' ? 'blue' : 'red', // Langsung pakai 'warna'
color: 'white',
padding: '10px',
margin: '5px',
border: 'none',
borderRadius: '5px',
cursor: 'pointer'
};return (
{teks} {/ Langsung pakai 'teks' /}
);
}
Ini bikin kode lebih ringkas dan mudah dibaca karena kita langsung tahu props apa aja yang dibutuhkan komponen ini di baris pertama.
PropTypes: Validasi Props Biar Aman
Saat aplikasi makin besar, penting buat mastiin komponen menerima props dengan tipe data yang benar. Misalnya, komponen Tombol
tadi seharusnya nerima teks
yang tipenya string dan warna
juga string. Kalau nggak, bisa error atau tampilan jadi kacau.
React punya library namanya prop-types
buat validasi ini. Ini bukan pengganti TypeScript, tapi sangat membantu kalau kamu belum pakai TypeScript.
- Install dulu library-nya:
bash
npm install prop-types
# atau
yarn add prop-types
- Import di file komponen:
javascript
// src/components/Tombol.js (Dengan PropTypes)import React from 'react';
import PropTypes from 'prop-types'; // Import PropTypesfunction Tombol({ teks, warna }) {
const styleTombol = {
backgroundColor: warna === 'biru' ? 'blue' : 'red',
color: 'white',
padding: '10px',
margin: '5px',
border: 'none',
borderRadius: '5px',
cursor: 'pointer'
};return (
{teks}
);
}// Tambahkan properti propTypes ke komponen
Tombol.propTypes = {
teks: PropTypes.string.isRequired, // 'teks' harus string dan wajib ada
warna: PropTypes.string // 'warna' harus string (tidak wajib)
// Bisa juga pakai .oneOf(['biru', 'merah']) untuk pilihan tertentu
};// Bisa juga kasih nilai default kalau props nggak dikasih
Tombol.defaultProps = {
warna: 'biru' // Kalau 'warna' nggak dikasih, defaultnya 'biru'
};
Kalau sekarang kamu manggil , React akan kasih peringatan di console browser saat mode development. Berguna banget buat debugging!
Mengelola Data Internal dengan State (pakai useState Hook)
Props itu buat data yang datang dari luar komponen. Tapi gimana kalau komponen itu sendiri punya data yang bisa berubah seiring waktu karena interaksi user? Misalnya, angka di komponen counter yang bertambah tiap diklik, atau status toggle (on/off). Data yang berubah di dalam komponen itu namanya state.
Di Komponen Fungsional, kita pakai useState
Hook buat mengelola state.
useState
itu fungsi dari React yang kalau dipanggil akan me-return sepasang nilai dalam array:
- Nilai state saat ini.
- Sebuah fungsi buat mengupdate nilai state itu.
Contoh: Bikin komponen Counter.js
javascript
// src/components/Counter.jsimport React, { useState } from 'react'; // Import useState Hookfunction Counter() {
// Deklarasi state baru bernama 'count'
// useState(0) artinya nilai awal 'count' adalah 0
// 'setCount' adalah fungsi untuk mengupdate 'count'
const [count, setCount] = useState(0);const increment = () => {
// Memanggil setCount untuk mengubah nilai count
// React akan me-render ulang komponen ini dengan nilai count yang baru
setCount(count + 1);
};const decrement = () => {
setCount(count - 1);
};return (
Hitungan: {count} {/ Tampilkan nilai state /}
Tambah {/ Panggil fungsi saat button diklik /}
Kurang
);
}
Penjelasan:
import { useState } from 'react';
: Kita importuseState
dari React.const [count, setCount] = useState(0);
: Ini cara deklarasi state.
* count
: Nama variabel untuk state-nya. * setCount
: Nama fungsi untuk mengupdate count
. Konvensi namanya biasanya set
diikuti nama state-nya (dengan huruf pertama kapital). * useState(0)
: Memanggil Hook-nya dengan nilai awal state (dalam contoh ini, angka 0).
Hitungan: {count}
: Kita bisa langsung pakai variabelcount
di JSX buat nampilin nilai state saat ini.- : Atribut
onClick
di elemen HTML di React itu menerima fungsi. Jadi, saat tombol "Tambah" diklik, fungsiincrement
akan dijalankan. setCount(count + 1);
: Di dalam fungsiincrement
, kita memanggilsetCount
dengan nilai baru untukcount
. Penting: Selalu update state pakai fungsisetCount
atau yang sejenisnya yang diberikan olehuseState
. Mengubah state secara langsung (count = count + 1;
) tidak akan membuat komponen me-render ulang dan state-nya tidak terdeteksi berubah oleh React.
Setiap kali setCount
dipanggil, React akan tahu bahwa state komponen Counter
berubah dan akan me-render ulang (re-render) komponen itu dengan nilai count
yang terbaru. Ajaib kan?
Melakukan "Side Effects" dengan useEffect Hook
Kadang, komponen kita perlu ngelakuin sesuatu setelah render selesai. Misalnya, ngambil data dari API saat komponen pertama kali muncul di layar, mengatur timer, langganan (subscribe) ke event tertentu, atau berinteraksi langsung sama DOM. Hal-hal ini disebut side effects.
Di Komponen Fungsional, kita pakai useEffect
Hook buat ngurusin side effects.
useEffect
itu fungsi yang nerima dua argumen:
- Fungsi callback yang akan dijalankan setelah render.
- Dependency Array (opsional) - array yang berisi nilai-nilai (props atau state) yang kalau berubah, fungsi callback
useEffect
akan dijalankan lagi.
Contoh: Ngambil data dari API saat komponen pertama kali muncul
javascript
// src/components/DataFetcher.jsimport React, { useState, useEffect } from 'react'; // Import useState dan useEffectfunction DataFetcher() {
const [data, setData] = useState(null); // State buat nyimpan data
const [loading, setLoading] = useState(true); // State buat indikator loading
const [error, setError] = useState(null); // State buat nyimpan error// useEffect dengan dependency array kosong []
useEffect(() => {
console.log("useEffect jalan..."); // Buat debugging
// Fungsi async buat ngambil data
async function fetchData() {
try {
const response = await fetch('https://swapi.dev/api/people/1/'); // Contoh API publik
if (!response.ok) {
throw new Error(HTTP error! status: ${response.status});
}
const result = await response.json();
setData(result); // Update state data
} catch (e) {
setError(e); // Update state error
} finally {
setLoading(false); // Set loading jadi false
}
}fetchData(); // Panggil fungsi fetch data// Cleanup function (opsional, untuk membersihkan side effect)
return () => {
console.log("useEffect cleanup...");
// Contoh: batalin request, unsubscribe, clear timer
};}, []); // Dependency array kosong: effect hanya jalan sekali setelah initial renderif (loading) return Lagi loading...;
if (error) return Ada error: {error.message};return (
Data yang Diambil:
{data && ( // Tampilkan kalau data ada
Nama: {data.name}
Tinggi: {data.height} cm
Massa: {data.mass} kg
)}
);
}
Penjelasan tentang Dependency Array:
[]
(Array Kosong): Effect hanya dijalankan sekali setelah render pertama (miripcomponentDidMount
pada komponen kelas). Ini paling umum buat ngambil data saat komponen muncul atau setup listener/subscription awal.
Tanpa Dependency Array (dihilangkan): Effect akan dijalankan setelah setiap render (mirip componentDidMount
+ componentDidUpdate
). Hati-hati pakai ini karena bisa bikin infinite loop* kalau update state di dalamnya tanpa kondisi yang pas. Umumnya jarang dipakai.
[prop1, state1, ...]
(Array dengan Nilai): Effect akan dijalankan setelah render pertama dan setiap kali nilai-nilai yang ada di dalam array dependensi berubah. Ini berguna kalau effect kamu bergantung pada nilai props atau state tertentu.
Cleanup Function:
Kalau fungsi callback di useEffect
menginisiasi sesuatu yang perlu dihentikan atau dibersihkan (kayak langganan ke event, timer, koneksi network), kamu bisa me-return sebuah fungsi dari callback useEffect
itu. Fungsi yang di-return ini akan dijalankan saat komponen akan di-unmount (dihapus dari DOM) atau sebelum effect dijalankan lagi kalau dependensinya berubah. Ini penting buat mencegah memory leaks.
Struktur Komponen dan Best Practices
Bikin komponen itu nggak cuma soal sintaks, tapi juga gimana menatanya biar rapi dan gampang di-maintain. Beberapa tips yang sering dipakai:
- Satu Komponen, Satu File: Pisahkan setiap komponen ke dalam file
.js
atau.jsx
terpisah. Ini bikin kodenya modular dan gampang dicari. - Nama File dan Komponen Kapital (PascalCase): Ikuti konvensi penamaan ini (
NamaKomponen.js
). - Struktur Folder: Atur komponenmu dalam folder. Misalnya, bikin folder
src/components/
. Untuk komponen yang lebih kompleks atau terkait, bisa bikin sub-folder lagi (src/components/Button/Button.js
,src/components/User/UserProfile.js
). - Komponen Kecil dan Fokus (Single Responsibility): Usahakan satu komponen hanya melakukan satu tugas utama. Kalau komponenmu jadi terlalu panjang atau ngurusin banyak hal, mungkin itu tanda perlu dipecah jadi komponen-komponen yang lebih kecil.
- Gunakan Props untuk Komunikasi Parent-Child: Kirim data dari komponen induk ke anak pakai props.
- Gunakan State untuk Data Internal: Kelola data yang hanya dibutuhkan dan berubah di dalam komponen itu sendiri pakai state.
- Conditional Rendering: Tampilkan atau sembunyikan elemen atau komponen lain berdasarkan kondisi tertentu. Bisa pakai
if/else
, operator ternary (kondisi ? trueRender : falseRender
), atau operator logika&&
(kondisi &&
).
javascript
function Greeting({ isLoggedIn }) {
if (isLoggedIn) {
return Selamat Datang Kembali!;
}
return Silakan Login.;
}function MaybeShowThing({ shouldShow }) {
return (
{shouldShow && Ini muncul kalau shouldShow true.}
);
}
- List Rendering: Kalau mau nampilin daftar item (misalnya, daftar produk), gunakan method
map
pada array. Penting: Setiap elemen dalam daftar yang dibuat pakaimap
harus punya propkey
yang unik.key
membantu React mengidentifikasi item mana yang berubah, ditambah, atau dihapus, sehingga proses update DOM lebih efisien.
javascript
function ItemList({ items }) {
return (
{items.map(item => (
{/ item.id harus unik /}
{item.name}
))}
);
}
Nilai key
sebaiknya berasal dari ID unik data itu sendiri (kayak item.id
). Hindari pakai index array sebagai key kalau urutan item bisa berubah atau item bisa ditambah/dihapus di tengah daftar, karena ini bisa menyebabkan masalah performa dan bug.
Komponen Komposisi (Composition)
Salah satu kekuatan besar React adalah kemampuannya untuk mengkomposisikan komponen. Artinya, kamu bisa menaruh komponen di dalam komponen lain. Ini mirip nesting elemen HTML, tapi di sini kita menestig komponen yang punya logika dan tampilan sendiri.
Contoh paling dasar ya kayak saat kita naruh di dalam App.js
. Tapi ada juga pola komposisi yang menarik, salah satunya menggunakan props.children
.
props.children
itu properti spesial yang otomatis ada kalau kamu membuka dan menutup tag komponen dan menaruh sesuatu di dalamnya:
javascript
// Komponen Card.js yang akan membungkus konten lain
function Card(props) {
const cardStyle = {
border: '1px solid #ccc',
padding: '15px',
margin: '10px',
borderRadius: '8px',
boxShadow: '2px 2px 8px rgba(0,0,0,0.1)',
backgroundColor: 'white'
};return (
{props.children} {/ Di sinilah konten yang diapit tag Card akan ditampilkan /}
);
}export default Card;// Cara pakainya di komponen lain (misal, App.js)
import React from 'react';
import Card from './components/Card';
import Tombol from './components/Tombol'; // Komponen Tombol dari contoh sebelumnyafunction App() {
return (
Contoh Komposisi
{/ Buka tag Card /}
{/ Konten di sini akan masuk ke props.children di komponen Card /}
Ini Judul di Dalam Card
Ini paragraf di dalam card. Bisa berisi teks, gambar, atau komponen lain.
{/ Komponen lain juga bisa! /}
{/ Card lain dengan konten berbeda /}
Card Kedua
Item 1
Item 2
);
}
Dengan pola komposisi ini, komponen Card
jadi fleksibel dan bisa dipakai buat membungkus konten apa aja, tanpa perlu tahu isinya apa di awal. Ini powerful banget buat bikin komponen UI yang generik kayak layout, modal, sidebar, dll.
Mengapa Belajar Komponen Itu Penting Banget?
- Reusability: Kamu bisa pakai komponen yang sama berkali-kali di tempat berbeda. Hemat waktu dan kode jadi nggak duplikat.
- Maintainability: Kalau ada bug atau perubahan di satu bagian UI, kamu cukup perbaiki di satu komponen aja, nggak perlu nyari di seluruh codebase.
- Readability: Kode jadi lebih terstruktur, kayak baca outline daripada teks panjang tanpa paragraf. Gampang buat developer lain (atau kamu di masa depan) ngertiin kodenya.
- Testability: Komponen yang kecil dan punya satu tanggung jawab itu lebih gampang diuji secara independen.
- Kolaborasi: Tim developer bisa ngerjain bagian UI yang berbeda secara paralel karena kodenya udah terbagi per komponen.
Penutup
Nah, itu dia panduan singkat tapi lengkap tentang gimana bikin komponen di ReactJS, terutama pakai cara modern Komponen Fungsional dengan Hooks. Kita udah bahas mulai dari yang paling basic, cara ngasih data lewat props, ngelola data internal pakai state (useState
), ngelakuin side effect pakai useEffect
, sampai tips dan trik best practice struktur dan komposisi komponen.
Konsep komponen ini adalah pondasi utama di React. Kalau kamu udah paham dan nyaman bikin komponen, ngatur props, state, dan effect-nya, perjalananmu di dunia React bakal jauh lebih mulus.
Ingat, kunci dari paham itu adalah praktik. Coba bikin komponen-komponen kecil sendiri, eksperimen sama props, state, dan effects. Bikin aplikasi sederhana yang pakai beberapa komponen yang saling berkomunikasi. Dari situ, kamu bakal nemuin "feel" yang pas dalam ngembangin aplikasi React.
Tetap semangat belajar, terus eksplorasi Hooks lain yang ada di React, dan jangan ragu baca dokumentasi resmi React karena itu sumber ilmu paling valid dan update. Selamat ngoding, guys!