Membuat timer dan counter sederhana menggunakan react natieve

React Native • State & Hooks

Membangun Aplikasi Counter & Timer dengan React Native

Dokumentasi pembelajaran tentang State dan Hooks pada React Native melalui pembuatan aplikasi Counter & Timer yang saling terhubung.

👨‍💻 Oleh: Siswa React Native 📱 Expo SDK 54 🧠 useState ⚙️ useEffect 🔗 State Integration

📌 Pengantar

Pada pembelajaran kali ini saya mempelajari konsep State dan Hooks pada React Native dengan membuat sebuah aplikasi sederhana yang menggabungkan fitur Counter dan Timer.

Aplikasi ini menggunakan dua Hooks utama, yaitu useState untuk menyimpan dan mengubah data yang bersifat dinamis, serta useEffect untuk menangani side effect, khususnya proses interval pada Timer.

Tujuan pembelajaran: memahami bukan hanya bagaimana tombol bekerja, tetapi juga bagaimana perubahan state menyebabkan tampilan dan perilaku aplikasi ikut berubah.

🚀 Fitur & Logika Aplikasi

🔢

Counter

Counter memiliki tombol +, −, dan Reset Counter. Nilainya disimpan menggunakan useState.

⏱️

Timer

Timer memiliki tombol Mulai, Stop, dan Reset. Waktu bertambah setiap satu detik menggunakan setInterval().

🔗

Interkoneksi State

Saat nilai Counter menjadi 0, Timer otomatis dihentikan dan tombol Mulai dinonaktifkan.

🎨

UI

Tampilan dibuat menggunakan card, status, tombol interaktif, dan layout responsif agar nyaman digunakan di browser maupun layar mobile.

🧠 Memahami useState

useState digunakan untuk menyimpan data yang dapat berubah pada komponen fungsional. Hook ini mengembalikan dua hal: nilai state saat ini dan fungsi untuk mengubah state.

Bentuk dasarnya adalah:

const [nilai, setNilai] = useState(initialValue);

Pada aplikasi ini, terdapat tiga state utama:

const [counter, setCounter] = useState(0);

const [seconds, setSeconds] = useState(0);

const [isRunning, setIsRunning] = useState(false);
State Fungsi
counter Menyimpan nilai Counter.
seconds Menyimpan jumlah waktu dalam detik.
isRunning Menentukan apakah Timer sedang berjalan atau berhenti.

Counter bertambah

setCounter((prev) => prev + 1);

Fungsi setter digunakan untuk memperbarui nilai state. Ketika setCounter() dipanggil, nilai counter berubah dan komponen akan menampilkan nilai terbaru.

Counter berkurang

setCounter((prev) => Math.max(0, prev - 1));

Math.max(0, ...) digunakan agar nilai Counter tidak pernah menjadi angka negatif. Jadi, nilai minimum Counter adalah 0.

Reset Counter

setCounter(0);

⚙️ Memahami useEffect

useEffect digunakan untuk menangani side effect. Contoh side effect antara lain timer, interval, pengambilan data dari API, dan proses cleanup.

Pada aplikasi ini, useEffect digunakan sebagai pengatur interval Timer.

useEffect(() => {
  let interval = null;

  if (isRunning) {
    interval = setInterval(() => {
      setSeconds((prev) => prev + 1);
    }, 1000);
  }

  return () => {
    if (interval) {
      clearInterval(interval);
    }
  };
}, [isRunning]);

Bagaimana cara kerjanya?

isRunning = true
↓
setInterval() dijalankan
↓
Setiap 1000 ms → seconds + 1
↓
isRunning = false
↓
clearInterval() → Timer berhenti

Dependency Array

Effect di atas memiliki dependency array [isRunning]. Artinya effect akan bereaksi ketika nilai isRunning berubah.

Cleanup

Bagian return merupakan fungsi cleanup. Cleanup berisi clearInterval() untuk membersihkan interval yang sebelumnya dibuat. Dengan demikian interval tidak terus berjalan ketika Timer sudah tidak aktif.

Intinya: useState menyimpan nilai dinamis, sedangkan useEffect membantu mengatur efek yang terjadi sebagai akibat dari perubahan state.

🔗 Hubungan Counter & Timer

Salah satu bagian penting dari tugas adalah membuat Counter dan Timer saling terhubung. Logikanya adalah ketika Counter kembali ke angka 0, Timer harus berhenti secara otomatis.

useEffect(() => {
  if (counter === 0) {
    setIsRunning(false);
  }
}, [counter]);

Dependency array di sini adalah [counter], sehingga effect dipicu ketika nilai Counter berubah.

Counter berubah
↓
useEffect mendeteksi [counter]
↓
Apakah counter === 0?
↓
Ya → setIsRunning(false)
↓
Timer berhenti otomatis
Contoh: ketika Counter bernilai 1, tombol Mulai dapat digunakan. Jika tombol − ditekan dan Counter kembali menjadi 0, Timer otomatis berhenti.

💻 Kode Program Utama (App.js)

Berikut bagian inti dari file App.js yang menunjukkan penerapan useState, useEffect, Counter, Timer, dan hubungan keduanya.

App.js — State
const [counter, setCounter] = useState(0);
const [seconds, setSeconds] = useState(0);
const [isRunning, setIsRunning] = useState(false);
App.js — Timer
useEffect(() => {
  let interval = null;

  if (isRunning) {
    interval = setInterval(() => {
      setSeconds((prev) => prev + 1);
    }, 1000);
  }

  return () => {
    if (interval) {
      clearInterval(interval);
    }
  };
}, [isRunning]);
App.js — Hubungan Counter & Timer
useEffect(() => {
  if (counter === 0) {
    setIsRunning(false);
  }
}, [counter]);
App.js — Counter Function
const increaseCounter = () => {
  setCounter((prev) => prev + 1);
};

const decreaseCounter = () => {
  setCounter((prev) => Math.max(0, prev - 1));
};

const resetCounter = () => {
  setCounter(0);
};
App.js — Timer Function
const startTimer = () => {
  if (counter > 0) {
    setIsRunning(true);
  }
};

const stopTimer = () => {
  setIsRunning(false);
};

const resetTimer = () => {
  setIsRunning(false);
  setSeconds(0);
};

Dengan struktur tersebut, aplikasi memiliki alur yang jelas: input pengguna mengubah state, state memengaruhi tampilan, dan useEffect menangani proses timer serta hubungan antar-state.

🛠️ Proses Pengerjaan

Membuat project React Native

Project dibuat menggunakan Expo dengan template blank dan Expo SDK 54 untuk pembelajaran menggunakan Expo Go.

Mengatur state

State untuk Counter, waktu Timer, dan status Timer dibuat dengan useState.

Membuat interval Timer

useEffect menjalankan setInterval() setiap 1000 milidetik ketika Timer aktif.

Menambahkan cleanup

clearInterval() digunakan pada cleanup agar interval dapat dihentikan ketika Timer tidak lagi aktif.

Menghubungkan Counter dengan Timer

Ketika Counter berubah menjadi 0, effect mengubah isRunning menjadi false sehingga Timer berhenti.

Melakukan pengujian

Counter, Timer, Reset, Stop, dan hubungan Counter = 0 → Timer Stop diuji satu per satu.

📸 Hasil Pengujian Aplikasi

Setelah program dijalankan, aplikasi berhasil menampilkan fitur Counter dan Timer dalam satu halaman. Screenshot berikut digunakan sebagai dokumentasi hasil praktik.

✅ Skenario Pengujian

Tombol + dapat menambah nilai Counter.
Tombol − dapat mengurangi nilai Counter.
Counter tidak dapat menjadi angka negatif.
Reset Counter mengembalikan nilai ke 0.
Timer dapat dimulai ketika Counter lebih dari 0.
Timer bertambah setiap satu detik.
Stop menghentikan Timer.
Reset Timer mengembalikan waktu ke 00:00.
Counter kembali ke 0 → Timer otomatis berhenti.
Catatan pengujian integrasi: nilai Counter sengaja dibuat lebih dari 0 sebelum Timer dijalankan. Setelah Counter dikurangi kembali menjadi 0, aplikasi mengubah status Timer menjadi berhenti secara otomatis.

⚠️ Kendala & Solusi

1. Gagal membuat template pada percobaan pertama

Pada percobaan awal, proses pembuatan template mengalami kegagalan ketika Expo mencoba mengunduh dan mengekstrak template SDK 54. Setelah cache npm diverifikasi dan project dibuat kembali menggunakan template blank@sdk-54, project berhasil dibuat.

2. Web support belum tersedia

Saat project pertama kali dijalankan sebagai web, muncul peringatan bahwa dependency web belum terpasang. Solusinya adalah memasang dependency yang dibutuhkan Expo untuk web, kemudian menjalankan project dengan target web.

3. Memahami interval dan cleanup

Timer tidak cukup hanya menggunakan state. Program juga membutuhkan setInterval() untuk menjalankan update secara berkala dan clearInterval() sebagai cleanup agar interval dapat dihentikan dengan benar.

📚 Apa yang Saya Pelajari?

Dari project ini saya memahami bahwa state merupakan data yang dapat berubah dan dapat memengaruhi tampilan komponen. Pada React Native, useState digunakan untuk menyimpan nilai tersebut dan setter digunakan untuk memperbaruinya.

Saya juga memahami bahwa useEffect digunakan untuk menangani side effect. Dalam project ini side effect tersebut berupa interval Timer. Dependency array menentukan state yang dipantau, sedangkan cleanup digunakan untuk membersihkan interval ketika sudah tidak diperlukan.

Selain itu, saya mempelajari bahwa beberapa state dapat dibuat saling berhubungan. Perubahan counter dapat memengaruhi isRunning, sehingga Timer dapat dikontrol berdasarkan kondisi Counter.

Ringkasnya: useState mengelola data yang berubah, useEffect mengelola side effect, dan keduanya dapat digunakan bersama untuk membuat interaksi aplikasi yang lebih dinamis.

💡 Kesimpulan

Aplikasi Counter & Timer berhasil dibuat menggunakan React Native dan Expo. Aplikasi menerapkan konsep State melalui useState serta konsep Side Effect melalui useEffect.

Counter digunakan untuk mengelola nilai angka, sedangkan Timer menggunakan setInterval() untuk menambah waktu setiap satu detik. Cleanup dengan clearInterval() digunakan untuk menghentikan interval ketika Timer tidak aktif.

Counter dan Timer juga dibuat saling terhubung. Ketika Counter bernilai 0, Timer otomatis berhenti. Dengan demikian, project ini tidak hanya memenuhi fitur dasar tugas, tetapi juga memberikan pemahaman mengenai hubungan state, event handling, side effect, cleanup, dan perubahan UI pada React Native.

Melalui tugas ini saya menjadi lebih memahami cara menggunakan Hooks pada komponen fungsional React Native dan cara menerapkan konsep tersebut dalam sebuah aplikasi mobile sederhana.

React Native • useState • useEffect • Counter & Timer

Dokumentasi pembelajaran dan hasil praktik aplikasi.

Comments

Popular posts from this blog

Latihan membuat tampilan flutter sederhana 🤖

Jenis-jenis sistem operasi os

Mobile development