Manajemen State Global dan Redux

Glovory Tech
11 min readOct 5, 2020

--

Illustration by Teddy Tri

Jika kita ingin membuat beberapa halaman yang menggunakan state yang sama dan sinkron (Jika terjadi perubahan state di halaman A maka halaman B juga harus berubah) pada react native, ada baiknya kita menggunakan satu sumber data yang sama untuk meyakinkan bahwa data yang diambil akan selalu sama. Dalam hal ini kita bisa menggunakan bantuan library yang disebut dengan redux. Singkatnya,

“redux adalah library yang dapat membantu mengatur state yang digunakan bersama oleh beberapa halaman / Komponen.”

redux.js.org

Pembahasan dan penerapan redux banyak sekali sulit dipahami oleh seseorang yang baru belajar react ataupun react native. Untuk itu saya akan jabarkan poin-poin penting yang harus diperhatikan sebelum kita mempelajari redux. Berikut adalah poin-poinnya:

1. Redux adalah library yang membantu kita dalam menangani state global (State yang sama yang dipakai di beberapa halaman / komponen).

2. Kalian masih bisa melakukan pengaturan state global dengan banyak halaman dengan akal-akalan, salah satunya dengan memanfaatkan bantuan library navigasi (Melempar data dari halaman satu ke halaman yang lain dengan library navigasi, seperti ReactNavigation dll). Namun cara tersebut memiliki beberapa kelemahan, Sebagai contoh, jika kita hanya ingin melempar data dari 2 halaman, itu masih cukup mudah untuk dilakukan. Namun lain cerita ketika navigasi yang ada terlalu dalam, misalkan dari halaman A ke B ke C dan ke D ? Bukankah kita harus mengecek satu per satu data yang kita lempar di setiap halaman tersebut ?, Masalah lain adalah jika halaman A dan B benar-benar terpisah sedangkan kedua halaman tersebut sebenarnya memiliki state yang sama namun tidak ada penghubung navigasi di kedua halaman tersebut, sehingga tidak memungkinkan kita untuk melempar data dari kedua halaman tersebut. Masalah yang sama jika kita membuat komponen-komponen yang terpisah pisah di react native.

3. Selanjutnya aplikasi-aplikasi seperti apa saja yang membutuhkan redux ? aplikasi kecil dan tidak terlalu kompleks seperti aplikasi list activity, game tic tac toe dan sebagainya, tidak wajib menggunakan redux. Namun aplikasi yang besar dan kompleks seperti toko online, marketplace dan sebagainya, sangat dianjurkan menggunakan redux.

4. Tidak perlu membuat redux untuk manajemen state dimana state tidak bersifat global(hanya dipakai di halaman itu saja, meskipun pada aplikasi yang cukup kompleks sekalipun) meskipun sebenarnya masih bisa dibuat redux-nya sih, tapi buat apa ?, itu buang-buang waktu saja :)

5. Redux tidak hanya membantu kita untuk memudahkan manajemen state antar halaman, tapi juga antara komponen induk(parent) dengan anaknya(child) begitu juga sebaliknya.

Jadi dari sini kita bisa tahu bahwa redux memang tidak wajib digunakan untuk setiap projek kita, namun itu akan sangat membantu kita mengatur state global apabila kita membuat aplikasi yang kompleks dan besar. Saran saya adalah, jika ternyata kalian masih bingung dengan konsep redux, silahkan saja membuat aplikasi kalian tanpa bantuan redux sampai pada titik kalian membutuhkan state manajemen yang lebih rapi dan mudah di-maintainance untuk aplikasi kalian.

A. Melempar Data Antar Halaman
Sebelum kita membahas tentang redux, kita akan membahas bagaimana melempar data antara halaman satu ke halaman yang lain tapi, jika kalian sudah tahu dan sangat familiar dengan cara ini, kalian bisa langsung membaca materi selanjutnya tentang manajemen redux. Supaya lebih jelas kita akan langsung mempraktikkannya. Contoh kasusnya adalah, kita akan membuat aplikasi data siswa sederhana, dimana halaman pertama akan menampilkan daftar siswa, jika kita tekan salah satu daftar nama yang ada, aplikasi akan berpindah ke halaman detail, dan aplikasi juga bisa menambah siswa baru ke dalam daftar. Pertama buat projek baru dengan perintah:

npx react-native init LatihanNavigationRedux

Kemudian setelah itu kita install library react-navigation kedalam projek baru kita tersebut. Perintahnya adalah:

npm install @react-navigation/native

Kemudian kita juga wajib menginstal dependency yang lainnya agar library react-navigation kita dapat berjalan dengan baik. Berikut adalah perintahnya:

npm install react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view

Untuk lebih jelasnya kalian juga bisa melihat dokumentasi yang sudah tersedia di halaman resminya di link berikut: https://reactnavigation.org/docs/getting-started

Karena disini kita akan menggunakan stack navigation, maka kita menambahkan library-nya ke dalam projek kita, dengan cara berikut:

npm install @react-navigation/stack

Setelah mengikuti semua langkah-langkah di atas, kemudian buatlah folder baru di dalam root projek kita dengan nama “src”, kemudian di dalam folder tersebut, buat lagi folder baru bernama “pages”. Selanjutnya, buat 4 file baru di dalam folder “pages” dengan nama: index.js, HomePage.js, AddPage.js dan DetailPage.js. Jika dilihat susunan folder kita akan menjadi seperti gambar di bawah:

Penjelasan dari keempat file tersebut adalah sebagai berikut:

1. index.js: Membantu kita melakukan import semua file yang ada di folder pages.

2. Home.js: Halaman awal dari aplikasi yang nantinya akan menampilkan daftar siswa

3. AddPage.js: Halaman untuk menambahkan data siswa baru

4. DetailPage.js: Halaman untuk melihat data detail dari siswa tertentu

Setelah itu, buka file App.js yang ada di folder root kemudian hapus semua isinya dan ganti dengan kode seperti ini.

Kode tersebut digunakan untuk melakukan inisialisasi rute navigasi pada aplikasi kita. Jika kita lihat disana ada 3 halaman yang akan kita gunakan yaitu halaman HOME sebagai halaman awal yang akan menampilkan daftar siswa, halaman ADD_PAGE sebagai halaman untuk menambahkan data baru dan terakhir adalah halaman DETAIL_PAGE yang akan kita gunakan untuk menampilkan informasi detail. Nah untuk langkah selanjutnya mari kita isikan kode berikut ke dalam masing-masing file, kemudian saya akan membahasnya satu-satu.

Kalian bisa membagi(split) layar kalian antara artikel ini dengan kode yang sudah kalian tulis agar lebih nyaman saat kalian membaca penjelasannya, berikut adalah penjelasan tentang kode yang sudah kita tulis / copy.

1. Halaman Home.js
Oke, sekarang kita lihat di halaman home, disana terdapat state dengan susunan id, name, phone, address dan hobby. Sebagai inisialisasi kita berikan 2 data pada state dataStudents, sehingga HOME_PAGE akan terlihat seperti berikut:

Beberapa hal yang menjadi fokus kita di halaman ini adalah:
Fungsi extractData() digunakan untuk menampilkan data-data yang ada pada state dataStudents, Di dalam fungsi tersebut terdapat fungsi lain bernama this.props.navigation.navigate(), fungsi ini digunakan untuk berpindah ke halaman DETAIL_PAGE dengan melempar variabel dataStudent dengan nilai state dataStudents yang ke-index. Contohnya, jika kita menekan card pertama(index ke 0), maka halaman detail akan menampilkan data detail dari dataStudents index yang ke 0, begitu seterusnya. Fungsi handleAddStudent() digunakan untuk menambahkan data siswa dan fungsi ini harus dilempar terlebih dahulu ke dalam halaman ADD_PAGE(AddPage.js) dengan bantuan library navigasi. Mengapa kita membuat fungsi handleAddStudent() di dalam halaman HOME_PAGE bukan di halaman ADD_PAGE ? ini karena state yang akan kita ubah (dataStudents) ada di halaman HOME_PAGE, jadi akan lebih mudah jika kita letakkan fungsi untuk melakukan handle state tersebut di halaman yang sama dimana state berada. Kemudian fungsi buttonAdd() digunakkan untuk menampilkan tombol yang apabila ditekan akan berpindah ke halaman ADD_PAGE, ada dua parameter yang terpenting disini, parameter pertama adalah nama halaman yang ingin kita kunjungi, dalam hal ini adalah ADD_PAGE (nama sesuai dengan yang tertulis di App.js ya…), parameter kedua digunakan untuk melempar fungsi handleAddStudent yang akan dieksekusi di halaman ADD_PAGE ketika user menekan tombol SAVE.

2. Halaman AddPage.js
Pada halaman ADD_PAGE, terdapat state untuk menampung data siswa baru yang strukturnya sama dengan state dataStudents di halaman home di mana terdapat id, name, phone address dan hobby. Yang terpenting dan menjadi fokus kita di halaman ini adalah fungsi saveStudent(). Fungsi ini akan terpanggil ketika kita menekan tombol SAVE di bagian paling bawah form. Sesaat setelah kita menekan tombol saveStudent(), kita harus memanggil fungsi handleAddStudent() yang sudah kita lempar sebelumnya dari halaman HOME, hal ini perlu agar data yang baru, dapat dimasukkan ke dalam daftar siswa yang ada di halaman HOME. Fungsi yang digunakan untuk menangkap dan menjalankan fungsi lemparan dari halaman lain adalah this.props.route.params.nameOfFunction() Silahkan isi form yang ada, kemudian tekan tombol save.

Berikut adalah tampilan setelah kalian menambahkan data baru:

3. Halaman DetailPage.js
Pada halaman DETAIL_PAGE, terdapat fungsi untuk menangkap data yang sudah dilempar di halaman home sebelumnya. Untuk menangkap data lemparan, kita menggunakan fungsi yang sama seperti ketika kita melempar fungsi handleAddUser() di halaman ADD_PAGE, yaitu this.props.route.params.nameOfParameter. Karena kita melemparkan data dengan nama dataStudent maka untuk mengambil nilainya adalah this.props.route.params.dataStudent.name dan seterusnya.

B. Manajemen State Global Menggunakan Redux
Kita sudah tahu bagaimana cara melempar data dari satu halaman ke halaman yang lain. Hal ini bisa kita lakukan juga dengan menggunakan redux. Dengan kasus / aplikasi yang sama, kita akan melakukan hal serupa yaitu menampilkan data siswa, menambahkan siswa baru dan melihat detail data siswa tertentu, bedanya kali ini kita akan menggunakan bantuan redux. Sebelumnya, kita install dulu react-redux dan redux, dengan perintah sebagai berikut:

npm install redux react-redux

Setelah terinstall, langkah selanjutnya adalah membuat folder baru di dalam folder “src”. Namakan dengan ‘store’ (sebenarnya terserah saja namanya, saya menggunakan nama tersebut, jadi untuk mempermudah bisa kita samakan saja nama foldernya ya). Nah di dalam folder store ini terdapat bagian yang sangat amat penting agar kita bisa memahami dan menggunakan redux dengan baik. Beberapa bagian tersebut adalah:

1. Reducers
Bagian ini berisi tentang state global yang nantinya bisa dipakai di halaman manapun yang membutuhkan data tersebut. Di bagian ini juga terdapat fungsi yang digunakan untuk menampilkan atau memanipulasi (update / delete) state tersebut.

2. Actions
Bagian ini berisi action type, yaitu variabel untuk menamai jenis-jenis action apa saja yang nanti bisa dijalankan dalam reducers. Di bagian ini juga terdapat fungsi penghubung antara fungsi action dan fungsi yang ada di reducers. Jadi, dalam penggunaanya nanti, kita tidak secara langsung menggunakan fungsi yang ada pada reducer, tapi melalui fungsi penghubung ini.

Sekarang kita buat folder baru di dalam folder store dengan nama actions dan reducers, dan masih di folder yang sama, buat file bernama configureStore.js

Sekarang buat file-file berikut dan tulis / copy kode yang ada di bawah, kemudian akan saya jelaskan satu persatu. Silahkan tulis / copy kode berikut:

  1. Buat file bernama student.js di folder reducers, kemudian tulis / copy kode berikut
  2. Buat file bernama student.js juga di folder action, kemudian tulis / copy kode berikut
  3. Buat file bernama actionTypes.js di folder action, kemudian tulis / copy kode berikut
  4. Kemudian tulis kode berikut di file configureStore.js yang kita buat sebelumnya
  5. Ubah kode di file index.js yang ada di folder root, dengan kode berikut

1.student.js (di Folder reducers)
Jadi, file ini berisi state yang akan kita tetapkan sebagai state global (bisa diakses di halaman atau komponen mana saja di dalam aplikasi kita). Pada halaman ini terdapat fungsi studentReducer(). Pada fungsi tersebut, kita hanya melakukan handle pada action yang bertipe studentAction.STUDENT_ADD(menambahkan data baru) saja. Jenis-jenis action.type nya sendiri dijabarkan di folder actions tepatnya di file actionTypes. Jika kita ingin menambahkan manipulasi lain dalam reducer, maka kita harus menambahkan fungsi action dan action types nya juga. Sebagai catatan kita tidak membutuhkan actionTypes dan fungsi lain jika kita hanya ingin mengambil data.

2. student.js (di Folder actions)
Pada file, ini terdapat fungsi penghubung antara state dan halaman-halaman yang ingin memanipulasi state global. Pada halaman ini kita akan menuliskan fungsi addStudent() dimana nilai return dari fungsi tersebut akan ditangkap oleh parameter action di halaman student.js di folder reducers (silahkan buka file tersebut untuk lebih jelasnya, kemudian amati). Reducer akan menyesuaikan action.type yang ditangkap, kemudian menjalankan kode serta mengembalikan return sesuai action.type tersebut.

3. actionTypes.js (di Folder actions)
Di halaman ini terdapat enum atau lebih mudahnya, actionTypes ini digunakan untuk menamai jenis-jenis manipulasi data apa saja yang mungkin bisa dilakukan di reducers. Sebagai contoh disini kita ingin melakukan manipulasi penambahan data pada state dataStudents, jadi kita akan memberikan satu tipe STUDENT_ADD. Jika kita lihat nilai tipe dari addStudent.js di folder action akan bertipe student.STUDENT_ADD, tipe ini akan ditangkap di halaman student.js di folder reducers, kemudian fungsi akan memberikan return atau menjalankan fungsi yang sesuai dengan action.type — nya.

4. configureStore
Halaman ini digunakan untuk melakukan konfigurasi terhadap sistem redux yang kita buat. Hal penting yang perlu kita perhatikan disini adalah fungsi combineReducers(). Pada fungsi ini kita membuat sebuah objek dengan nama tertentu yang nantinya digunakan untuk berinteraksi dengan reducer yang ada, disini saya memberikan nama student dan dengan nilai studentReducer. Sebagai catatan, nama student bersifat bebas, kalian bisa menggunakan nama sesuka kalian seperti reduxStudent, globalStudent, dan lain sebagainya.

5. File index.js (di Folder Root)
Pada halaman ini kita melakukan import configureStore, kemudian memasukkannya ke parameter store di komponen Provider. Setelah itu komponen App akan dibungkus dengan komponen Provider tersebut. Secara sederhananya, kita menyediakan state global pada komponen provider, sehingga komponen lain dibawah provider, seperti App beserta anak-anaknya bisa menggunakan dan memanipulasi state global yang disediakan oleh Provider (dalam hal ini state yang ada pada dataStudents di file student.js pada folder reducers) tersebut.

Nah, setelah kita menyelesaikan langkah-langkah diatas, sekarang kita bisa mengakses dan memanipulasi state tersebut di komponen atau halaman manapun yang kita inginkan. Seperti sebelumnya, tuliskan / copy kode-kode berikut, kemudian saya akan menjelaskannya satu persatu.

  1. Ubah kode di file HomePage.js
  2. Ubah kode di file AddPage.js
  3. Ubah kode di file DetailPage.js

Sekarang jika kita jalankan aplikasi kita, tidak ada perbedaan dengan sebelumnya. Berikut adalah penjelasn kode tersebut:

1. HomePage.js
Jadi jika suatu halaman ingin menggunakan / mengakses state global yang sudah kita buat, langkah pertama adalah import connect dari library react redux. Karena pada halaman home kita hanya ingin mengambil data dataStudents dan tidak ingin memanipulasinya (tambah, ubah atau delete), maka kita hanya akan menghubungkannya dengan datanya saja, caranya adalah dengan bantuan mapStateToProps(). Ketika dijalankan kita bisa mengakses datanya melalui props (this.props.dataStudents), dan karena sebelumnya pada configureStore kita menamai properti objek penghubung reducer kita dengan nama ‘student’ (lihat file configureStore.js), maka untuk mengaksesnya, disini kita tuliskan dengan cara state.nameOnConfigure.nameOfState atau state.student.dataStudent. Dan dapat kita lihat data yang ada pada halaman HOME_PAGE ini diambil dari reducer student, bukan lagi dari local state, sekarang coba tambahkan 1 data lagi di file student pada folder reducers dan lihat hasilnya.

2. AddPage.js
Hampir sama dengan halaman HOME_PAGE, pada halaman ADD_PAGE ini, kita akan menghubungkannya dengan state global. Namun bedanya, pada halaman ini kita hanya akan melakukan manipulasi data (menambahkan data baru) dan tidak mengambil / menampilkan datanya. Langkahnya hampir sama, hanya saja kali ini kita harus melakukan import addStudent dari folder actions/student. Seperti penjelasan saya sebelumnya, kita membutuhkan fungsi penghubung untuk kemudian diteruskan ke dalam reducers sehingga data dapat dimanipulasi. Jika kita ingin mengirim state global kepada props, kita menggunakan fungsi mapStateToProps, maka jika kita ingin menghubungkan sebuah fungsi manipulasi, kita akan menggunakan mapDispatchToProps(). Pada fungsi connect(), parameter pertama wajib diisi null, karena kita tidak sedang mengambil data dataStudents tapi hanya ingin melakukan manipulasi saja. Dengan demikian hanya parameter kedua yang kita isi dengan mapDispatchToProps. Jika kalian ingin menampilkan data sekaligus melakukan manipulasi, maka kedua parameter connect harus diisi. Jika kita perhatikan pada fungsi saveStudent(). Dapat kita lihat bahwa sekarang kita tidak memanipulasi state yang ada di halaman HOME_PAGE, tapi kita memanipulasi secara langsing state global dengan fungsi onAddStudent(). Apabila kita jalankan dan kembali ke halaman HOME_PAGE, dapat kita lihat bahwa data yang ada sekarang bertambah sesuai data yang kita masukkan.

3. DetailPage.js
Untuk menampilkan halaman detail page berbeda dengan sebelumnya. Jika sebelumnya kita melemparkan data siswa secara utuh(lengkap) ke dalam halaman DETAIL_PAGE, kali ini kita cukup melemparkan data index, kemudian pada halaman DETAIL_PAGE, kita lakukan sinkronisasi terhadap data global seperti pada halaman HOME_PAGE dengan fungsi mapStateToProps(). Kemudian untuk mengambil data detail / spesifiknya, kita hanya tinggal menangkap index lemparan dan menuliskannya seperti ini: this.props.dataStudents[this.props.route.params.idx].specificData.

Nah demikian kira-kira, perbedaannya manajemen state menggunakan redux dan tidak menggunakan redux. Semoga artikel ini bermanfaat, mohon maaf jika ada salah dalam tulisan kali ini, sampai jumpa di artikel berikutnya :)

Contributor : Virginia Hendras

--

--

Glovory Tech
Glovory Tech

Written by Glovory Tech

We are a comprehensive digital product agency specializing in UI/UX design & development of websites and mobile applications, IoT, AI, and custom software dev.

No responses yet