Belajar React Native - State, Props & Hooks
Episode 5 of 23

Belajar React Native - State, Props & Hooks

Episode ini membedah state, props, dan hooks di React Native: useState, useEffect, useRef, useMemo, dan useCallback, pola komposisi komponen, serta typing props dengan TypeScript agar kode aman dari kesalahan tipe.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Pendahuluan

Di episode 4 kalian belajar membuat tampilan statis. Sekarang tampilan itu perlu hidup: merespons ketukan tombol, memuat data dari server, dan menyimpan nilai input. Semua itu dikendalikan oleh state, props, dan hooks — konsep yang sama dengan React di web, tapi dengan nuansa mobile. Episode 5 membedah hooks yang paling sering dipakai — useState, useEffect, useRef, useMemo, dan useCallback — lalu bagaimana menyusun komponen dengan props dan komposisi, serta typing props menggunakan TypeScript. Ini adalah jantung logika interaktif aplikasi kalian.

State dengan useState

Membuat Counter Sederhana

useState menyimpan nilai yang bisa berubah dan memicu re-render saat berubah:

JSCounter dengan useState
import React, { useState } from "react";
import { View, Text, Pressable, StyleSheet } from "react-native";
 
export function Counter() {
  const [count, setCount] = useState(0);
 
  return (
    <View style={styles.box}>
      <Text style={styles.label}>{count}</Text>
      <Pressable style={styles.button} onPress={() => setCount(count + 1)}>
        <Text>Tambah</Text>
      </Pressable>
    </View>
  );
}

Perhatikan pola pada Counter: useState(0) menginisialisasi state dengan 0, dan setCount(count + 1) memperbarui nilai. Setiap panggilan setCount memicu re-render dengan nilai baru.

State pada TextInput

Pola yang sangat umum di mobile adalah mengikat TextInput ke state:

JSTextInput terkontrol
const [nama, setNama] = useState("");
 
<TextInput
  value={nama}
  onChangeText={setNama}
  placeholder="Masukkan nama"
  style={styles.input}
/>

value={nama} dan onChangeText={setNama} membuat input ini terkontrol penuh — nilai selalu sinkron dengan state nama. Pola ini dasar untuk form, pencarian, dan chat.

Efek Samping dengan useEffect

Kapan useEffect Dibutuhkan

useEffect menangani efek samping: mengambil data, subscribe event, atau mengubah hal di luar render. Di mobile, lifecycle komponen mengikuti mounting dan unmounting yang sama dengan React web:

JSuseEffect untuk fetch data
import React, { useState, useEffect } from "react";
import { View, Text } from "react-native";
 
export function UserStatus() {
  const [status, setStatus] = useState("memuat...");
 
  useEffect(() => {
    let aktif = true;
    fetch("https://api.example.com/status")
      .then((res) => res.json())
      .then((data) => {
        if (aktif) setStatus(data.status);
      });
    return () => {
      aktif = false;
    };
  }, []);
 
  return (
    <View>
      <Text>Status: {status}</Text>
    </View>
  );
}

Pola pada UserStatus di atas memperlihatkan dua kebiasaan penting: dependency array kosong [] artinya efek hanya berjalan sekali setelah mount, dan fungsi cleanup aktif = false mencegah pembaruan state setelah komponen unmount — mencegah error umum di React Native.

Efek yang Bergantung pada Props

Jika efek memakai nilai dari props atau state, masukkan nilai itu ke dependency array. Misalnya useEffect(..., [userId]) akan menjalankan ulang fetch setiap kali userId berubah — pola dasar untuk layar detail.

Memegang Nilai Stabil dengan useRef

useRef menyimpan nilai yang tidak memicu re-render saat berubah, dan nilainya bertahan seumur hidup komponen. Dua pemakaian utama:

  • Menyimpan referensi ke komponen native, misalnya ScrollView untuk scroll programatik.
  • Menyimpan nilai mutable yang sering berubah tanpa perlu render ulang, seperti timer atau id interval.

Contoh pemakaian kedua: timerRef.current menyimpan id interval yang di-set oleh setInterval dan dibersihkan oleh clearInterval. Karena tidak memicu render, menyimpannya di useRef jauh lebih bersih daripada di useState.

Optimasi Memo dan Callback

useMemo untuk Nilai Berat

useMemo meng-cache hasil perhitungan yang mahal. Nilai di dalamnya hanya dihitung ulang saat dependency berubah:

JSuseMemo untuk data terurut
const daftarUrut = useMemo(() => {
  return daftar.sort((a, b) => b.skor - a.skor);
}, [daftar]);

useCallback untuk Fungsi Stabil

useCallback mengembalikan referensi fungsi yang sama selama dependency tidak berubah. Ini penting saat fungsi diteruskan sebagai prop ke komponen anak yang di-memo — mencegah re-render yang tidak perlu di episode 8.

JSuseCallback untuk handler
const onKlik = useCallback(() => {
  console.log("diklik");
}, []);

Props dan Komposisi dengan TypeScript

Typing Props

TypeScript membuat kontrak komponen eksplisit. Definisikan props sebagai interface dan tandai optional dengan tanda tanya:

JSTyping props dengan TypeScript
type ButtonProps = {
  title: string;
  onPress: () => void;
  disabled?: boolean;
};
 
export function Button({ title, onPress, disabled = false }: ButtonProps) {
  return (
    <Pressable onPress={onPress} disabled={disabled}>
      <Text>{title}</Text>
    </Pressable>
  );
}

Pada Button di atas, disabled? bersifat optional dengan default false. Saat memanggil <Button title="Simpan" onPress={simpan} />, editor langsung memvalidasi props yang dikirim.

Komposisi: Anak sebagai Prop

JSKomposisi dengan children
type CardProps = {
  children: React.ReactNode;
};
 
export function Card({ children }: CardProps) {
  return <View style={styles.card}>{children}</View>;
}

Dengan pola ini, <Card><Text>Konten bebas</Text></Card> bekerja untuk konten apa pun. Komposisi lebih fleksibel daripada menebak semua kombinasi props.

Tip

Pisahkan komponen "dumb" (hanya menerima props dan merender) dari komponen "smart" yang memegang state. Struktur ini membuat logika mudah dites dan dipakai ulang, seperti yang akan kalian lihat di episode 20.

Penutup

Episode 5 menghidupkan aplikasi kalian: state dengan useState, efek samping dengan useEffect, nilai stabil dengan useRef, optimasi dengan useMemo dan useCallback, serta kontrak props yang aman berkat TypeScript.

Inti yang harus dibawa pulang:

  • useState menyimpan nilai yang memicu re-render.
  • useEffect menangani efek samping, dengan cleanup untuk mencegah update setelah unmount.
  • useRef menyimpan nilai stabil yang tidak memicu re-render.
  • useMemo meng-cache hasil kalkulasi; useCallback menstabilkan referensi fungsi.
  • TextInput terkontrol mengikat value ke state.
  • Typing props dengan interface TypeScript mencegah banyak bug sebelum runtime.

Di episode 6 selanjutnya kita akan membahas navigasi: React Navigation dengan stack, tab, dan drawer, alternatif file-based Expo Router, serta konfigurasi deep linking untuk membuka layar tertentu dari URL.

Belajar React Native - State, Props & Hooks | Belajar React Native