Reactjs Component Props State Render Flow
Selesai membaca dokumentasi ini?
Kembali ke rujukan utama React.js untuk melanjutkan topik lainnya.
Kembali ke rujukan utama React.js untuk melanjutkan topik lainnya.
Di React.js, UI dibangun dari component. Setiap component menerima data dari luar lewat props, menyimpan data lokal tertentu lewat state, lalu menghasilkan tampilan melalui proses render.
Kalau disederhanakan:
Topik ini penting karena hampir semua keputusan arsitektur React berputar di sekitar empat hal itu.
Gunakan pemahaman props dan state untuk membedakan:
Kalau batas ini kabur, komponen biasanya cepat membesar, state jadi tersebar, dan rerender terasa “random” padahal sebenarnya mengikuti alur data yang cukup jelas.
Component adalah fungsi atau kelas yang mengembalikan UI.
Dalam praktik modern, yang paling sering dipakai adalah function component.
function ProfileCard() {
return <div>Profile</div>;
}Component bisa dipecah jadi bagian kecil supaya:
Props adalah input untuk component.
Data ini mengalir dari parent ke child dan sifatnya read-only dari sudut pandang child.
function Greeting({ name }) {
return <p>Halo, {name}</p>;
}
function App() {
return <Greeting name="Alya" />;
}Di sini, App mengirim name ke Greeting. Greeting hanya membaca nilai itu, bukan mengubahnya.
Props cocok untuk data seperti:
State adalah data yang hidup di dalam component dan bisa berubah.
State dipakai saat component perlu menyimpan informasi yang memengaruhi render berikutnya.
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(count +
State cocok untuk:
Props adalah jalur utama untuk mengalirkan data dari atas ke bawah.
Urutannya begini:
function UserRow({ user }) {
return <li>{user.name}</li>;
}
function UserList({ users }) {
return (
<ul>
{users.map((user) => (
Poin pentingnya:
Props sering dipakai untuk membentuk komponen yang presentational: fokus pada tampilan, bukan pengambilan data.
State dipakai kalau data tersebut:
Kalau data hanya lewat sebagai parameter tampilan, biasanya cukup pakai props.
Contoh yang sering keliru:
function Price({ amount }) {
const [formatted, setFormatted] = useState(`Rp ${amount}`);
return <p>{formatted}</p>;
}Kalau formatted hanya turunan dari amount, state di sini justru tidak perlu. Lebih aman dihitung langsung:
function Price({ amount }) {
return <p>Rp {amount}</p>;
}State tambahan yang tidak perlu sering jadi sumber bug sinkronisasi.
Rerender terjadi saat React perlu menghitung ulang tampilan component karena ada perubahan pada input render.
Pemicunya yang umum:
Yang penting dipahami: rerender bukan berarti DOM langsung ditulis ulang seluruhnya. React lebih dulu menjalankan ulang fungsi component untuk membandingkan hasil render, lalu memperbarui bagian yang memang berubah.
Saat satu state berubah di parent, React biasanya mengevaluasi ulang parent terlebih dulu. Setelah itu, child yang berada di bawahnya juga bisa ikut dievaluasi karena parent mengirim props baru atau karena subtree-nya dipanggil ulang.
Diagram ini tidak berarti semua node selalu benar-benar mengubah DOM. Yang terjadi adalah React mengecek ulang hasil render dari jalur yang terdampak.
Kadang state dipindahkan ke child karena terlihat “lebih rapi”, padahal parent masih butuh mengendalikan data itu.
Akibatnya:
Kalau dua komponen perlu membaca nilai yang sama, biasanya state lebih aman ditempatkan di ancestor terdekat yang relevan.
Kalau data harus diteruskan melalui banyak level hanya untuk sampai ke satu child, struktur mulai terasa berat.
Contoh gejala:
props bertambah panjang tanpa alasan jelasSolusi bisa berupa:
Derived state adalah nilai yang sebenarnya bisa dihitung dari props atau state lain.
Kalau disimpan lagi sebagai state terpisah, risikonya:
Kalau bisa dihitung saat render, biasanya lebih baik dihitung saat render.
Memecah komponen memang bagus, tapi terlalu agresif juga bisa bikin struktur tidak enak dibaca.
Tanda-tandanya:
Prinsipnya: pecah berdasarkan tanggung jawab, bukan sekadar demi memecah.
Komponen yang bagus biasanya punya peran jelas:
Kalau semua logic disebar ke mana-mana, flow data jadi sulit diprediksi.
function SearchPage() {
const [query, setQuery] = useState('');
return (
<div>
<SearchInput value={query} onChange={setQuery} />
Di sini:
SearchPage menyimpan state querySearchInput menerima value dan onChange lewat propsSearchResultList juga membaca query sebagai propsPola ini membuat sumber data jelas: satu state utama, beberapa child yang membaca inputnya.