Cara Kerja Redux Reducer

Diterbitkan: 2022-03-10
Ringkasan cepat Jika Anda pernah menggunakan Redux kapan saja saat mengembangkan aplikasi untuk mengelola state , Anda pasti akan menemukan reduksi. Tutorial ini akan menjelaskan konsep reduksi dan cara kerjanya secara khusus di Redux.

Dalam tutorial ini, kita akan mempelajari konsep reduksi dan cara kerjanya, khususnya dalam aplikasi React. Untuk memahami dan menggunakan Redux dengan lebih baik, pemahaman yang kuat tentang reduksi sangat penting. Reducer menyediakan cara untuk memperbarui status aplikasi menggunakan suatu tindakan. Ini adalah bagian integral dari perpustakaan Redux.

Tutorial ini untuk pengembang yang ingin mempelajari lebih lanjut tentang Redux Reducers. Pemahaman tentang React dan Redux akan bermanfaat. Di akhir tutorial, Anda harus memiliki pemahaman yang lebih baik tentang peran yang dimainkan Reducer di Redux. Kami akan menulis demo kode dan aplikasi untuk lebih memahami Reducer dan bagaimana pengaruhnya terhadap status dalam aplikasi.

Apa itu Peredam?

Reducer adalah fungsi murni yang mengambil status aplikasi dan tindakan sebagai argumen dan mengembalikan status baru. Misalnya, peredam autentikasi dapat mengambil status awal aplikasi dalam bentuk objek kosong dan tindakan yang memberitahukannya bahwa pengguna telah masuk dan mengembalikan status aplikasi baru dengan pengguna yang masuk.

Fungsi murni adalah fungsi yang tidak memiliki efek samping dan akan mengembalikan hasil yang sama jika argumen yang sama diteruskan.

Di bawah ini adalah contoh fungsi murni:

 const add = (x, y) => x + y; add(2, 5);

Contoh di atas mengembalikan nilai berdasarkan input, jika Anda melewati 2 dan 5 maka Anda akan selalu mendapatkan 7 , selama inputnya sama tidak ada lagi yang memengaruhi output yang Anda dapatkan, itu adalah contoh fungsi murni.

Di bawah ini adalah contoh fungsi peredam yang mengambil keadaan dan tindakan.

 const initialState = {}; const cartReducer = (state = initialState, action) => { // Do something here }

Mari kita definisikan dua parameter yang digunakan peredam, state dan action .

Lebih banyak setelah melompat! Lanjutkan membaca di bawah ini

Negara

Status adalah data yang digunakan oleh komponen Anda — status ini menampung data yang dibutuhkan komponen dan menentukan apa yang dirender oleh komponen. Setelah objek state berubah, komponen dirender ulang. Jika status aplikasi dikelola oleh Redux, maka peredam adalah tempat terjadinya perubahan status.

Tindakan

Sebuah tindakan, adalah sebuah objek yang berisi muatan informasi. Mereka adalah satu-satunya sumber informasi untuk toko Redux yang akan diperbarui. Reducer memperbarui toko berdasarkan nilai dari action.type . Di sini kita akan mendefinisikan action.type sebagai ADD_TO_CART .

Menurut dokumentasi Redux resmi, tindakan adalah satu-satunya hal yang memicu perubahan dalam aplikasi Redux, tindakan tersebut berisi muatan untuk perubahan pada toko aplikasi. Tindakan adalah objek JavaScript yang memberi tahu Redux jenis tindakan yang akan dilakukan, biasanya didefinisikan sebagai fungsi seperti di bawah ini:

 const action = { type: 'ADD_TO_CART', payload: { product: 'margarine', quantity: 4 } }

Kode di atas adalah nilai payload tipikal yang berisi apa yang dikirim pengguna dan akan digunakan untuk memperbarui status aplikasi. Seperti yang Anda lihat dari atas, objek tindakan berisi jenis tindakan dan objek muatan yang diperlukan untuk tindakan tertentu yang akan dilakukan.

Memperbarui Status Menggunakan Pereduksi

Untuk menunjukkan cara kerja reduksi, mari kita lihat penghitung angka di bawah ini:

 const increaseAction = { type: 'INCREASE', }; const decreaseAction = { type: 'DECREASE' }; const countReducer = (state = 0, action) => { switch(action.type){ case INCREASE: return state + 1; case DECREASE : return state -1; default: return state; } };

Dalam kode di atas, increaseAction dan decreaseAction adalah tindakan yang digunakan dalam peredam untuk menentukan state diperbarui ke apa. Selanjutnya, kita memiliki fungsi peredam yang disebut countReducer , yang mengambil action dan state awal yang nilainya 0 . Jika nilai dari action.type adalah INCREASE , kami mengembalikan status baru yang bertambah 1, jika tidak, akan DECREASE status baru yang dikurangi 1. Dalam kasus di mana tidak ada kondisi yang dimaksudkan, kami mengembalikan state .

Memperbarui Status Menggunakan Pereduksi: Operator Spread

Status tidak dapat diubah secara langsung, untuk membuat atau memperbarui status, kita dapat menggunakan operator penyebaran JavaScript untuk memastikan bahwa kita tidak mengubah nilai status secara langsung, melainkan mengembalikan objek baru yang berisi status yang diteruskan ke sana dan muatan pengguna.

 const contactAction = { type: 'GET_CONTACT', payload: ['0801234567', '0901234567'] }; const initialState = { contacts: [], contact: {}, }; export default function (state = initialState, action) { switch (action.type) { case GET_CONTACTS: return { ...state, contacts: action.payload, }; default: return state; }

Pada kode di atas, kita menggunakan operator spread untuk memastikan kita tidak mengubah nilai state secara langsung, dengan cara ini kita dapat mengembalikan objek baru yang diisi dengan state yang diteruskan dan payload yang dikirim oleh pengguna. Dengan menggunakan operator spread, kita dapat memastikan bahwa status tetap sama saat kita menambahkan semua item baru ke dalamnya dan juga mengganti bidang kontak di status jika ada sebelumnya.

Pengurang Redux Beraksi — Demo

Untuk lebih memahami Redux Reducers dan cara kerjanya, kami akan menerapkan aplikasi pencari detail Film sederhana, kode dan versi kerja dapat ditemukan di sini di Codesandbox. Untuk memulai, buka terminal Anda dan inisialisasi aplikasi reaksi menggunakan perintah di bawah ini:

 create-react-app movie-detail-finder

Setelah proyek kita diinisialisasi, selanjutnya mari kita instal paket-paket yang kita perlukan untuk aplikasi kita.

 npm i axios reactstrap react-redux redux redux-thunk

Setelah paket diinstal, mari kita mulai server pengembangan kita menggunakan perintah:

 npm start

Perintah di atas harus memulai server pengembangan proyek kami di browser kami. Selanjutnya mari kita buka proyek kita di editor teks pilihan kita, di dalam folder src proyek kita, hapus file-file berikut: App.css , App.test.js , serviceWorker.js dan setupTests.js . Selanjutnya, mari kita hapus semua kode yang mereferensikan file yang dihapus di App.js kita.

Untuk proyek ini, kami akan menggunakan Open Movie Database API untuk mendapatkan informasi film, konten, dan gambar untuk aplikasi kami, berikut adalah tautan ke API, Anda harus mendaftar dan mendapatkan kunci akses untuk menggunakannya untuk ini aplikasi, Setelah Anda selesai, mari kita lanjutkan dengan aplikasi kita dengan membangun komponen.

Membangun Komponen Aplikasi

Pertama, di dalam folder src kami di direktori proyek kami, buat folder bernama komponen dan di dalam folder, mari buat dua folder bernama Movie dan Searchbar , komponen kita akan terlihat seperti gambar di bawah ini:

folder komponen
folder komponen. (Pratinjau besar)

Membangun Komponen Film

Mari kita buat komponen Movies , yang akan menguraikan struktur detail film yang akan kita dapatkan dari API kita. Untuk melakukan ini, di dalam folder Movies dari komponen kita, buat file baru Movie.js , selanjutnya buat komponen berbasis kelas untuk hasil API, mari kita lakukan di bawah ini.

 import React, { Component } from 'react'; import { Card, CardImg, CardText, CardBody, ListGroup, ListGroupItem, Badge } from 'reactstrap'; import styles from './Movie.module.css'; class Movie extends Component{ render(){ if(this.props.movie){ return ( <div className={styles.Movie}> <h3 className="text-center my-4"> Movie Name: {this.props.movie.Title} </h3> <Card className="text-primary bg-dark"> <CardImg className={styles.Img} top src={this.props.movie.Poster} alt={this.props.movie.Title}/> <CardBody> <ListGroup className="bg-dark"> <ListGroupItem> <Badge color="primary">Actors:</Badge> {this.props.movie.Actors} </ListGroupItem> <ListGroupItem> <Badge color="primary">Genre:</Badge> {this.props.movie.Genre} </ListGroupItem> <ListGroupItem> <Badge color="primary">Year:</Badge> {this.props.movie.Year} </ListGroupItem> <ListGroupItem> <Badge color="primary">Writer(s):</Badge> {this.props.movie.Writer} </ListGroupItem> <ListGroupItem> <Badge color="primary">IMDB Rating:</Badge> {this.props.movie.imdbRating}/10 </ListGroupItem> </ListGroup> <CardText className="mt-3 text-white"> <Badge color="secondary">Plot:</Badge> {this.props.movie.Plot} </CardText> </CardBody> </Card> </div> ) } return null } } export default Movie;

Pada kode di atas, Menggunakan komponen dari paket reactstrap , Anda dapat melihat dokumentasinya di sini. Kami membangun komponen Kartu yang mencakup nama film, Gambar, genre, aktor, tahun, penulis film, peringkat, dan plot. Untuk memudahkan dalam melewatkan data dari komponen ini, kami membangun data untuk dijadikan sebagai penyangga komponen lainnya. Selanjutnya, mari kita buat komponen Searchbar kita.

Membangun Komponen Searchbar Kami

Komponen Searchbar kami akan menampilkan bilah pencarian dan komponen tombol untuk mencari komponen film, mari lakukan ini di bawah ini:

 import React from 'react'; import styles from './Searchbar.module.css'; import { connect } from 'react-redux'; import { fetchMovie } from '../../actions'; import Movie from '../Movie/Movie'; class Searchbar extends React.Component{ render(){ return( <div className={styles.Form}> <div> <form onSubmit={this.formHandler}> <input type="text" placeholder="Movie Title" onChange={e => this.setState({title: e.target.value})} value={this.state.title}/> <button type="submit">Search</button> </form> </div> <Movie movie={this.props.movie}/> </div> ) } }

Dalam kode di atas, kita mengimpor connect dari react-redux yang digunakan untuk menghubungkan komponen React ke toko Redux, menyediakan komponen dengan informasi dari toko dan juga menyediakan fungsi yang digunakan untuk mengirimkan tindakan ke toko. Selanjutnya, kami mengimpor komponen Movie dan fungsi fetchMovie dari actions.

Selanjutnya, kita memiliki tag form dengan kotak input untuk memasukkan judul film kita, menggunakan hook setState dari React, kita menambahkan event dan nilai onChange yang akan mengatur status title ke nilai yang dimasukkan di kotak input. Kami memiliki tag button untuk mencari judul film dan menggunakan komponen Movie yang kami impor, kami meneruskan properti komponen sebagai props ke hasil pencarian.

Selanjutnya bagi kami adalah menulis fungsi untuk mengirimkan judul film kami ke API untuk mengirimkan hasil kepada kami, kami juga perlu mengatur status awal aplikasi. mari kita lakukan di bawah ini.

 class Searchbar extends React.Component{ state = { title: '' } formHandler = (event) => { event.preventDefault(); this.props.fetchMovie(this.state.title); this.setState({title: ''}); }

Di sini, kita menyetel status awal aplikasi ke string kosong, kita membuat fungsi formHandler yang mengambil parameter peristiwa dan meneruskan fungsi fetchMovie dari aksi dan menyetel judul sebagai status baru aplikasi. Untuk melengkapi aplikasi kita, mari ekspor komponen ini menggunakan properti connect dari react-redux , untuk melakukan ini kita akan menggunakan properti react mapToStateProps untuk memilih bagian data yang dibutuhkan komponen kita, Anda dapat mempelajari lebih lanjut tentang mapToStateProps di sini.

 const mapStateToProps = (state) => { return { movie: state.movie } } export default connect(mapStateToProps, { fetchMovie })(Searchbar)

Mari tambahkan gaya ke formulir kita dengan membuat file Searchbar.module.css dan menambahkan gaya di bawah ini:

 .Form{ margin: 3rem auto; width: 80%; height: 100%; } input{ display: block; height: 45px; border: none; width: 100%; border-radius: 0.5rem; outline: none; padding: 0 1rem; } input:focus, select:focus{ border: 2px rgb(16, 204, 179) solid; } .Form button{ display: block; background: rgb(16, 204, 179); padding: 0.7rem; border-radius: 0.5rem; width: 20%; margin-top: 0.7rem; color: #FFF; border: none; text-decoration: none; transition: all 0.5s; } button:hover{ opacity: 0.6; } @media(max-width: 700px){ input{ height: 40px; padding: 0 1rem; } .Form button{ width: 40%; padding: 0.6rem; } }

Setelah kami melakukan hal di atas, komponen bilah pencarian kami akan terlihat mirip dengan gambar di bawah ini:

Komponen bilah pencarian
Komponen bilah pencarian. (Pratinjau besar)

Membuat Tindakan Untuk Aplikasi

Dalam komponen ini, kita akan mengatur tindakan Redux untuk aplikasi kita, Pertama, di dalam direktori src , buat folder bernama actions dan di dalam folder, kita akan membuat file index.js . Di sini kita akan membuat fungsi fetchMovie yang mengambil parameter judul, dan mengambil film dari API menggunakan Axios. Mari kita lakukan ini di bawah ini:

 import axios from 'axios'; export const fetchMovie = (title) => async (dispatch) => { const response = await axios.get( `https://cors-anywhere.herokuapp.com/https://www.omdbapi.com/?t=${title}&apikey=APIKEY`); dispatch({ type: 'FETCH_MOVIE', payload: response.data }) }

Pada kode di atas, kami mengimpor axios dan membuat fungsi yang disebut fetchMovie yang mengambil parameter title dengan menggunakan async/await sehingga kami dapat membuat permintaan ke server API. Kami memiliki fungsi dispatch yang mengirimkan ke Redux objek tindakan yang diteruskan ke sana. Dari apa yang kami miliki di atas, kami mengirimkan tindakan dengan tipe FETCH_MOVIE dan payload yang berisi respons yang kami dapatkan dari API.

CATATAN: apikey dalam permintaan akan diganti dengan apikey Anda sendiri setelah mendaftar di OmdbAPI .

Membuat Pereduksi Aplikasi

Di bagian ini, kita akan membuat reduksi untuk aplikasi kita.

 const fetchMovieReducer = (state = null, action) => { switch(action.type){ case 'FETCH_MOVIE': return action.payload; default: return state; } } const rootReducer = (state, action) => { return { movie: fetchMovieReducer(state, action) } } export default rootReducer;

Pada kode di atas, kami membuat fetchMovieReducer yang mengambil status default null dan parameter action , menggunakan operator sakelar, untuk kasus FETCH_MOVIE kami akan mengembalikan nilai action.payload yang merupakan film yang kami dapatkan dari API. Jika tindakan yang kami coba lakukan tidak ada di peredam, maka kami mengembalikan status default kami.

Selanjutnya, kami membuat fungsi rootReducer yang akan menerima status saat ini dan tindakan sebagai input dan mengembalikan fetchMovieReducer .

Menyatukannya

Di bagian ini, kami akan menyelesaikan aplikasi kami dengan membuat toko redux kami di index.js , mari lakukan itu di bawah ini:

 import React from 'react'; import ReactDOM from 'react-dom'; import { Provider } from 'react-redux'; import { createStore, applyMiddleware } from 'redux'; import thunk from 'redux-thunk'; import App from './App'; import 'bootstrap/dist/css/bootstrap.min.css'; import './index.css'; import reducers from './reducers'; const store = createStore(reducers, applyMiddleware(thunk)) ReactDOM.render( <Provider store={store}> <> <App/> </> </Provider>, document.getElementById('root') )

Pada kode di atas, kami membuat store aplikasi menggunakan metode createStore dengan melewatkan peredam yang kami buat dan middleware. Middlewares adalah add-on yang memungkinkan kita untuk meningkatkan fungsionalitas Redux. Di sini kita menggunakan middleware Redux Thunk menggunakan applyMiddleware . Middleware Redux Thunk diperlukan untuk toko kami untuk melakukan pembaruan asinkron. Ini diperlukan karena secara default, Redux memperbarui toko secara sinkron.

Untuk memastikan aplikasi kami mengetahui toko yang tepat untuk digunakan, kami membungkus aplikasi kami dalam komponen Provider dan meneruskan toko sebagai penyangga, dengan melakukan ini, komponen lain dalam aplikasi kami dapat terhubung dan berbagi informasi dengan toko.

Mari tambahkan sedikit gaya ke file index.css kita.

 *{ margin: 0; padding: 0; box-sizing: border-box; } body{ background: rgb(15, 10, 34); color: #FFF; height: 100vh; max-width: 100%; }

Merender Dan Menguji Pencari Detail Film

Di bagian ini, kita akan menyimpulkan aplikasi kita dengan merender aplikasi kita di App.js , untuk melakukan ini, mari buat komponen berbasis kelas bernama App dan inisialisasi Searchbar dan bidang input kita.

 import React from 'react'; import Searchbar from './components/Searchbar/Searchbar'; import styles from './App.module.css'; class App extends React.Component{ render(){ return( <div className={styles.App}> <h1 className={styles.Title}>Movies Search App</h1> <Searchbar/> </div> ) } } export default App;

Di sini, kami membuat komponen berbasis kelas Aplikasi dengan h1 yang mengatakan Aplikasi Pencarian Film dan menambahkan komponen Searchbar Pencarian kami. Aplikasi kita akan terlihat seperti gambar di bawah ini:

aplikasi detail film dengan reduksi
Aplikasi detail film akhir menggunakan reduksi. (Pratinjau besar)

Demo yang berfungsi tersedia di Codesandbox.

Kesimpulan

Reducer adalah bagian penting dari manajemen status Redux, dengan reduksi kita dapat menulis fungsi murni untuk memperbarui area tertentu dari aplikasi Redux kita tanpa efek samping. Kami telah mempelajari dasar-dasar reduksi Redux, kegunaannya, dan konsep inti reduksi, status, dan argumen.

Anda dapat melangkah lebih jauh dengan melihat dokumentasi tentang reduksi Redux di sini. Anda dapat mengambil ini lebih jauh dan membangun lebih banyak pada reduksi Redux, beri tahu saya apa yang Anda buat.

Sumber daya

  • Dokumentasi React-Redux
  • Dokumentasi redux
  • connect() fungsi
  • applyMiddleware fungsi middleware