Terakhir diperbarui: 2024-03-20

Redux di ReactJS

Pada codelab ini Anda akan mempelajari tentang penggunaan library Redux di ReactJS, apa itu Redux, kegunaannya, dan kapan waktu yang tepat untuk menggunakan Redux tersebut.

Pengetahun yang Anda harus miliki

Sebelum memulai codelab ini, sebaiknya Anda memiliki pengetahuan dasar tentang:

Apa yang Anda akan pelajari

Apa yang Anda perlu persiapkan

Anda akan bingung tentang Redux jika membaca dari berbagai sumber di internet. Namun, dalam codelab ini akan disampaikan secara jelas kegunaan Redux dan kapan waktu yang tepat untuk memanfaatkan Redux dalam aplikasi kita.

Mengapa menggunakan Redux ?

Pertanyaan terbaik untuk memulai adalah dengan mengetahui alasannya mengapa kita harus menggunakan Redux ? dan jawabannya bukan karena semua orang atau developer menggunakan Redux juga.

Redux adalah alat manajemen state untuk aplikasi JavaScript. Redux menyediakan central store untuk application state dengan memberikan cara yang tepat untuk memperbarui nilai state yang disimpan dan mengambil nilai tersebut. Dengan adanya centralized store, menjadi lebih mudah untuk menulis aplikasi dan mengelola state.

Dalam Next.js terdapat beberapa library yang bisa digunakan untuk menerapkan redux, seperti redux-toolkit yang digunakan untuk mempermudah dan membantu untuk fast development, dan redux-persist yang digunakan untuk menyimpan redux store ke dalam localStorage, sehingga datanya tidak hilang saat browser di close dan ini cocok untuk proses user authorization.

Tentang Aliran Data (Data Flow)

Pada codelab sebelumnya Anda telah mempelajari props dan aliran data searah. Data dikirim ke komponen melalui props. Sebagai contoh, perhatikan komponen berikut:

Variabel count disimpan dalam state aplikasi, kemudian dikirim melalui props untuk melakukan update nilai variabel tersebut.

Agar data dapat mengalir dari bawah ke atas (maksudnya dari variabel props menjadi state aplikasi), maka diperlukan callback function sehingga data dapat di-update atau manipulasi oleh sebuah komponen button seperti pada ilustrasi berikut.

Anda dapat mengimajinasikan data seperti komponen elektronik yang saling terhubung dengan kabel yang memiliki warna-warna berbeda. Data mengalir melalui kabel-kabel tersebut antar komponen yang bisa saling bertukar data antar komponen tersebut.

Lapisan dalam Aliran Data

Cepat atau lambat Anda akan dihadapkan pada situasi di mana saat membuat aplikasi React membutuhkan lapisan data yang sama pada beberapa letak di halaman web. Perhatikan ilustrasi halaman web Twitter berikut yang menampilkan avatar (foto profil) pada 3 posisi berbeda, namun sumber datanya tetap sama.

Kita anggap avatar user merupakan bagian dari data profil user, yang disimpan dalam komponen App sebagai variabel user. Untuk mengirimkan data user ke tiga komponen avatar tersebut, data user perlu melewati beberapa komponen yang sebenarnya komponen-komponen tersebut tidak membutuhkannya. Perhatikan ilustrasi berikut ini.

Dari ilustrasi di atas, kita perhatikan data user melakukan perjalanan yang cukup rumit antar komponen-komponen yang berada dibawahnya. Model perancangan komponen seperti ini tidak baik untuk software design. Untuk melakukan refactoring dan reusing komponen cukup sulit jika berdasarkan ilustrasi tersebut. Karena setiap komponen memiliki state dan props-nya masing-masing.

Nah, itu merupakan salah satu masalah yang diselesaikan oleh Redux. Mari kita lanjutkan materi berikut ini.

Mudahnya Pasang Data ke Komponen dengan Redux

Redux menyelesaikan masalah ini. Redux memberikan kemudahan untuk memasang data yang dibutuhkan ke komponen apapun secara langsung (direct access).

Menggunakan fungsi connect yang ada dalam Redux, Anda dapat mengaitkan dengan komponen ke dalam data store milik Redux. Komponen dapat menggunakan data yang diperlukan saja. Perhatikan ilustrasi berikut ini.

Itulah alasan menggunakan Redux.

Selain itu, Redux memiliki manfaat lain yaitu:

  1. Redux DevTools, membuat proses debugging lebih mudah untuk melakukan inspeksi setiap perubahan state yang terjadi.
  2. Time-travel debugging, berfungsi untuk kembali ke masa lalu (perubahan state sebelumnya) dan dapat dilihat data state sebelumnya seperti apa.
  3. Kode aplikasi lebih mudah dikelola atau manajemen dalam jangka waktu yang lama, selain itu mengajarkan kepada Anda tentang functional programming.

Kemudahan memasang data ke berbagai komponen merupakan fungsi utama Redux, jika Anda tidak membutuhkan fitur tersebut, maka kemungkinan besar Anda tidak perlu untuk menggunakan Redux.

Kapan menggunakan Redux ?

Beberapa kondisi yang perlu dipertimbangkan ketika akan menggunakan Redux adalah sebagai berikut.

  1. Jika memiliki struktur komponen seperti ilustrasi sebelumnya yang telah dijelaskan, maka diperlukan Redux karena data props akan diteruskan ke berbagai komponen berbeda.
  2. Jika Anda membutuhkan cache data antar views atau UI, maka diperlukan Redux. Contohnya, memuat data ketika user mengklik halaman detail, beberapa data perlu disimpan untuk akses yang lebih cepat.
  3. Jika aplikasi React berskala besar dengan mengelola data yang banyak dan performa yang baik, maka diperlukan Redux. Namun, bisa dimulai membuat aplikasi React tanpa Redux terlebih dahulu, kemudian jika dihadapkan pada situasi yang sulit untuk mengelola data state aplikasi, maka saat itu bisa menambahkan library Redux.

Diagram Konsep Redux

Untuk memahami tentang konsep Redux, perhatikan diagram berikut:

Keterangan diagram:

  1. Action: merupakan objek JavaScript ("{ }") yang memberitahu reducer untuk memodifikasi data. Syaratnya, action harus memiliki properti type berupa String.
  2. Reducer: sebuah function yang memiliki kembalian data (return some data).
  3. State: merupakan data yang digunakan oleh aplikasi. Misalnya, value dari input field, data list, gambar, seluruh data aplikasi yang dikumpulkan menjadi state.
  4. Store: sebuah container yang menyimpan reducer dan state aplikasi.

Terdapat beberapa library atau toolkit yang disediakan untuk mengimplementasikan redux pada next.js diantaranya

1. redux-toolkit

redux-toolkit adalah sebuah toolkit resmi yang disediakan oleh tim pengembang Redux untuk memudahkan penggunaan Redux dalam pengembangan aplikasi JavaScript. Ini dirancang untuk mempercepat proses pengembangan aplikasi dengan Redux, menyediakan serangkaian utilitas dan fungsi yang memudahkan pengelolaan state, penanganan aksi, dan pembuatan reducer.

Beberapa fitur utama dari redux-toolkit meliputi:

  1. createSlice: Fungsi ini memungkinkan pengguna untuk membuat "slice" reducer, yang merupakan kombinasi dari action creators dan reducer dalam satu entitas. Ini mengurangi boilerplate code dan mempercepat proses pengembangan.
  2. configureStore: redux-toolkit menyediakan fungsi configureStore yang memfasilitasi konfigurasi toko Redux dengan opsi default yang direkomendasikan. Ini termasuk middleware, devtools, dan pengaturan lainnya yang sering digunakan.
  3. createAsyncThunk: Untuk menangani pemanggilan asynchronous seperti pemanggilan API, redux-toolkit menyediakan createAsyncThunk yang memudahkan pembuatan action creators yang melakukan pemanggilan async dan mengelola status loading, sukses, dan error secara otomatis.
  4. createEntityAdapter: Fungsi ini menyediakan utilitas untuk membuat adapter entitas, yang memfasilitasi manajemen entitas dalam store Redux dengan struktur data tertentu.

Dengan menggunakan redux-toolkit, pengguna dapat mengurangi kompleksitas dan boilerplate code yang terkait dengan penggunaan Redux secara langsung. Ini membantu meningkatkan produktivitas pengembangan dan mempercepat proses pengembangan aplikasi JavaScript yang menggunakan Redux untuk manajemen state.

2. redux-persist

redux-persist adalah sebuah library yang memungkinkan penggunaan Redux dalam aplikasi JavaScript untuk menyimpan dan memulihkan state Redux ke dan dari penyimpanan persisten, seperti local storage atau AsyncStorage di lingkungan React Native.

Dengan redux-persist, pengguna dapat membuat konfigurasi sederhana untuk menyimpan state Redux secara otomatis setiap kali ada perubahan, dan memulihkannya saat aplikasi dimuat kembali. Ini membantu menjaga persistensi data antara sesi aplikasi, sehingga pengguna dapat melanjutkan penggunaan aplikasi dari titik terakhirnya bahkan setelah aplikasi ditutup dan dibuka kembali.

redux-persist memiliki fitur-fitur yang memungkinkan pengguna untuk mengatur penyimpanan persisten, menyesuaikan perilaku penyimpanan, serta menambahkan transformasi data untuk menyesuaikan format penyimpanan. Ini sangat berguna untuk aplikasi yang memerlukan pengelolaan state yang persisten dan dapat diakses secara konsisten oleh pengguna.

3. next-redux-wrapper

next-redux-wrapper adalah sebuah library atau perpustakaan untuk integrasi Redux dengan aplikasi Next.js. Library ini menyediakan alat dan utilitas yang memudahkan penggunaan Redux dalam aplikasi Next.js, termasuk pengaturan awal untuk menyediakan toko Redux ke dalam aplikasi, pengelolaan state global, dan koneksi dengan komponen React di dalam aplikasi Next.js.

Dengan next-redux-wrapper, pengguna dapat mengintegrasikan Redux ke dalam aplikasi Next.js dengan lebih mudah, memungkinkan pengelolaan state aplikasi secara efisien dan konsisten di seluruh komponen. Ini membantu meningkatkan pengembangan aplikasi dengan memisahkan logika bisnis dari tampilan, dan menyediakan alur kerja yang jelas untuk mengelola state global.

Kita buka open folder untuk project pertemuan-06 di VS Code, maka isi direktori yang ada di dalamnya sedikit berbeda dengan project yang sudah pernah kita buat sebelumnya. Yaitu terdapat folder pages dan styles.

Kali ini kita coba pakai CSS Library Bootstrap dengan menjalankan perintah

npm install bootstrap

Kemudian kita import bootstrap pada aplikasi next.js kita. Kita edit file pages/_app.tsx

Sekarang kita perlu mencoba implementasi bootstrap pada project next.js kita.

Contoh kita edit file pages/index.tsx menjadi seperti ini

export default function Home() {
  return (      
    <div className="container">
      <div className="row">
        <div className="col-12">
          <button type="button"
                  className="btn btn-primary"
                  data-bs-toggle="modal"
                  data-bs-target="#exampleModal">
                  Coba Model Bootstrap
          </button>
        </div>
      </div>
      <div  className="modal fade"
            id="exampleModal"
            tabIndex="-1"
            aria-labelledby="exampleModalLabel"
            aria-hidden="true">
        <div className="modal-dialog">
          <div className="modal-content">
            <div className="modal-header">
              <h5 className="modal-title text-black" id="exampleModalLabel"> yay... </h5>
              <button
                type="button"
                className="btn-close"
                data-bs-dismiss="modal"
                aria-label="Close"></button>
            </div>
            <div className="modal-body text-black">
              <h2>Halo semua, kita sedang menggunakan bootstrap di Next.js</h2>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

Komponen yang digunakan pada praktikum kali ini adalah redux-toolkit dan redux-persistent sehingga kita perlu menginstall-nya

npm i --save redux-persist react-redux @reduxjs/toolkit

Selanjutnya kita install wrapper untuk redux di next.js

npm i --save next-redux-wrapper

Selain itu, kita akan menggunakan html parser yang ada di react. Hal ini kita gunakan untuk memparsing html string menjadi sebuah html page

npm install html-react-parser

Setelah berhasil menginstal kita cek di file package.json apakah library sudah ada

Selanjutnya, kita buat folder dengan nama redux yang sejajar dengan folder public

Kemudian kita buat file redux/auth/authSlice.js seperti berikut

Selanjutnya kita buat file redux/store/store.js seperti berikut

import { combineReducers, configureStore } from '@reduxjs/toolkit';
import authReducer from '../auth/authSlice';
import storage from 'redux-persist/lib/storage';
import { persistStore, persistReducer, FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER } from 'redux-persist';

const persistConfig = {
   key: process.env.NEXT_PUBLIC_FINGERPRINT_NAME,   // simpan config di file .env.local
   storage,
   whitelist: ['auth'],
};

const rootReducer = combineReducers({
   auth: authReducer,
});

const persistedReducer = persistReducer(persistConfig, rootReducer);
const store = configureStore({
   reducer: persistedReducer,
   middleware: (getDefaultMiddleware) =>
      getDefaultMiddleware({
         serializableCheck: {
            ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
         },
      }),
});

const persistor = persistStore(store);
export { store, persistor };

Key pada persistConfig kita simpan pada file .env.local dengan tujuan agar konfigurasi lebih mudah dan aman. Sehingga jika belum ada file .env.local, kita buat dahulu

Selanjutnya, kita buat file baru di pages/login.tsx, dan kita tulis kode berikut

Jalankan project kita di browser, dan amati apa yang terjadi?

Pada praktikum ini, kita akan membuat program counter sederhana seperti pada gambar berikut ini.

Tampilan mungkin tidak semenarik pada gambar di atas, karena saat ini kita tidak fokus pada CSS-nya. Untuk membuat aplikasi tersebut, silakan lakukan langkah-langkah praktikum berikut.

Kita buat file di redux/counter/naikTurunSlice.js

Setelah itu kita modifikasi redux/store/store.js untuk menambahkan Redux reducer pada store

Selanjutnya kita buat halaman untuk menampilkan counter.

Kita buat file baru di pages/counter.tsx

Kemudian kita jalankan di browser dengan url localhost:3000/counter, dan amati apa yang terjadi?

Berdasarkan pada praktikum sebelumnya yang telah dilakukan, beberapa pertanyaan terkait praktikum perlu diselesaikan yaitu sebagai berikut.

  1. Apa kegunaan dari kode ini import { useEffect } from "react"; Pada file pages/_app.tsx? jelaskan
  2. Jika pada file pages/_app.tsx kita tidak menggunakan useEffect (menghapus baris 3, dan baris 9-11, apa yang akan terjadi?
  3. Mengapa di react/nextjs penulisan tag html untuk class, harus diganti menjadi className ?
  4. Apakah store pada nextjs bisa menyimpan banyak redux reducer?
  5. Jelaskan kegunaan dari file store.js!
  6. Pada file pages/login.tsx, apa maksud dari kode ini ?
    const { isLogin } = useSelector((state) => state.auth);
  7. Pada file pages/counter.tsx, apa maksud dari kode ini?
    const {totalCounter} = useSelector((state) => state.counter);

Selamat, Anda telah berhasil menyelesaikan codelab ini. Semoga mendapatkan ilmu yang bermanfaat.

Apa selanjutnya?

Silakan cek beberapa sumber belajar lainnya...

Referensi