Menurut dokumen, "Tanpa middleware, Redux store hanya mendukung aliran data yang sinkron" . Saya tidak mengerti mengapa ini terjadi. Mengapa komponen kontainer tidak dapat memanggil API async, dan kemudian dispatch
tindakannya?
Misalnya, bayangkan UI sederhana: bidang dan tombol. Saat pengguna menekan tombol, bidang akan diisi dengan data dari server jarak jauh.
import * as React from 'react';
import * as Redux from 'redux';
import { Provider, connect } from 'react-redux';
const ActionTypes = {
STARTED_UPDATING: 'STARTED_UPDATING',
UPDATED: 'UPDATED'
};
class AsyncApi {
static getFieldValue() {
const promise = new Promise((resolve) => {
setTimeout(() => {
resolve(Math.floor(Math.random() * 100));
}, 1000);
});
return promise;
}
}
class App extends React.Component {
render() {
return (
<div>
<input value={this.props.field}/>
<button disabled={this.props.isWaiting} onClick={this.props.update}>Fetch</button>
{this.props.isWaiting && <div>Waiting...</div>}
</div>
);
}
}
App.propTypes = {
dispatch: React.PropTypes.func,
field: React.PropTypes.any,
isWaiting: React.PropTypes.bool
};
const reducer = (state = { field: 'No data', isWaiting: false }, action) => {
switch (action.type) {
case ActionTypes.STARTED_UPDATING:
return { ...state, isWaiting: true };
case ActionTypes.UPDATED:
return { ...state, isWaiting: false, field: action.payload };
default:
return state;
}
};
const store = Redux.createStore(reducer);
const ConnectedApp = connect(
(state) => {
return { ...state };
},
(dispatch) => {
return {
update: () => {
dispatch({
type: ActionTypes.STARTED_UPDATING
});
AsyncApi.getFieldValue()
.then(result => dispatch({
type: ActionTypes.UPDATED,
payload: result
}));
}
};
})(App);
export default class extends React.Component {
render() {
return <Provider store={store}><ConnectedApp/></Provider>;
}
}
Ketika komponen yang diekspor dirender, saya dapat mengklik tombol dan input diperbarui dengan benar.
Perhatikan update
fungsi dalam connect
panggilan. Ini mengirimkan tindakan yang memberi tahu App bahwa ia memperbarui, dan kemudian melakukan panggilan async. Setelah panggilan selesai, nilai yang diberikan dikirim sebagai muatan tindakan lain.
Apa yang salah dengan pendekatan ini? Mengapa saya ingin menggunakan Redux Thunk atau Redux Promise, seperti yang ditunjukkan oleh dokumentasi?
EDIT: Saya mencari repo Redux untuk mencari petunjuk, dan menemukan bahwa Pencipta Tindakan diharuskan untuk menjadi fungsi murni di masa lalu. Misalnya, inilah pengguna yang mencoba memberikan penjelasan yang lebih baik untuk aliran data async:
Pembuat tindakan itu sendiri masih merupakan fungsi murni, tetapi fungsi pukulan yang dikembalikan tidak perlu, dan dapat melakukan panggilan async kami
Pembuat aksi tidak lagi harus murni. Jadi, thidd / janji middleware pasti diperlukan di masa lalu, tetapi tampaknya ini tidak lagi terjadi?
sumber
Jawaban:
Tidak ada yang salah dengan pendekatan ini. Itu hanya merepotkan dalam aplikasi besar karena Anda akan memiliki komponen yang berbeda melakukan tindakan yang sama, Anda mungkin ingin mendebo beberapa tindakan, atau menjaga beberapa negara bagian seperti ID penambahan otomatis dekat dengan pembuat tindakan, dll. Jadi hanya lebih mudah dari sudut pandang pemeliharaan untuk mengekstrak pembuat tindakan ke dalam fungsi yang terpisah.
Anda dapat membaca jawaban saya untuk "Cara mengirim tindakan Redux dengan batas waktu" untuk penelusuran lebih rinci.
Middleware seperti Redux Thunk atau Redux Promise hanya memberi Anda "gula sintaksis" untuk mengirimkan barang atau janji, tetapi Anda tidak harus menggunakannya.
Jadi, tanpa middleware apa pun, pembuat tindakan Anda mungkin terlihat seperti
Tetapi dengan Thunk Middleware Anda dapat menulis seperti ini:
Jadi tidak ada perbedaan besar. Satu hal yang saya sukai dari pendekatan yang terakhir adalah bahwa komponen tidak peduli bahwa pembuat tindakan async. Itu hanya panggilan
dispatch
biasa, itu juga dapat digunakanmapDispatchToProps
untuk mengikat pembuat tindakan seperti itu dengan sintaks pendek, dll. Komponen tidak tahu bagaimana pembuat tindakan diimplementasikan, dan Anda dapat beralih di antara pendekatan async yang berbeda (Redux Thunk, Redux Promise, Redux Saga ) tanpa mengubah komponen. Di sisi lain, dengan pendekatan sebelumnya, eksplisit, komponen Anda tahu persis bahwa panggilan tertentu adalah async, dan perludispatch
dilewati oleh beberapa konvensi (misalnya, sebagai parameter sinkronisasi).Pikirkan juga bagaimana kode ini akan berubah. Katakanlah kita ingin memiliki fungsi pemuatan data kedua, dan untuk menggabungkannya dalam satu pembuat tindakan.
Dengan pendekatan pertama, kita perlu memperhatikan tindakan seperti apa yang kita panggil:
Dengan pembuat tindakan Redux Thunk dapat
dispatch
merupakan hasil dari pembuat tindakan lain dan bahkan tidak berpikir apakah itu sinkron atau tidak sinkron:Dengan pendekatan ini, jika nanti Anda ingin pembuat tindakan melihat keadaan Redux saat ini, Anda bisa menggunakan
getState
argumen kedua yang diteruskan ke thunks tanpa mengubah kode panggilan sama sekali:Jika Anda perlu mengubahnya agar sinkron, Anda juga dapat melakukan ini tanpa mengubah kode panggilan apa pun:
Jadi manfaat menggunakan middleware seperti Redux Thunk atau Redux Promise adalah bahwa komponen tidak menyadari bagaimana pembuat tindakan diimplementasikan, dan apakah mereka peduli dengan kondisi Redux, apakah mereka sinkron atau asinkron, dan apakah mereka memanggil pembuat tindakan lain atau tidak. . Kelemahannya adalah sedikit tipuan, tapi kami yakin ini layak dilakukan dalam aplikasi nyata.
Akhirnya, Redux Thunk dan teman-teman hanyalah salah satu pendekatan yang mungkin untuk permintaan asinkron di aplikasi Redux. Pendekatan lain yang menarik adalah Redux Saga yang memungkinkan Anda mendefinisikan daemon yang sudah berjalan lama (“sagas”) yang mengambil tindakan saat datang, dan mengubah atau melakukan permintaan sebelum menghasilkan tindakan. Ini memindahkan logika dari pencipta aksi ke kisah-kisah. Anda mungkin ingin memeriksanya, dan kemudian memilih yang paling cocok untuk Anda.
Ini salah. Dokter mengatakan ini, tetapi dokter itu salah.
Pembuat tindakan tidak pernah dituntut untuk menjadi fungsi murni.
Kami memperbaiki dokumen untuk mencerminkan hal itu.
sumber
alert
setelahdispatch()
tindakan.loadData(this.props.dispatch, this.props.userId); // don't forget to pass dispatch
. Mengapa saya harus mengirimkannya? Jika dengan konvensi hanya ada satu toko global saja, mengapa saya tidak melakukan rujukan langsung dan melakukannyastore.dispatch
kapan saja saya perlu, misalnya, diloadData
?store
contoh berbeda untuk setiap permintaan sehingga Anda tidak dapat mendefinisikannya sebelumnya.Kamu tidak.
Tapi ... Anda harus menggunakan redux-saga :)
Jawaban Dan Abramov benar tentang
redux-thunk
tetapi saya akan berbicara sedikit tentang redux-saga yang sangat mirip tetapi lebih kuat.Imperatif VS deklaratif
redux-thunk
sangat penting /redux-saga
bersifat deklaratifKetika Anda memiliki pukulan di tangan Anda, seperti monad IO atau janji, Anda tidak dapat dengan mudah tahu apa yang akan dilakukan setelah Anda mengeksekusi. Satu-satunya cara untuk menguji seorang thunk adalah dengan mengeksekusinya, dan mengejek dispatcher (atau seluruh dunia luar jika berinteraksi dengan lebih banyak barang ...).
Jika Anda menggunakan tiruan, maka Anda tidak melakukan pemrograman fungsional.
Sumber
Kisah-kisah (ketika mereka diterapkan di
redux-saga
) adalah deklaratif dan seperti komponen Free monad atau Bereaksi, mereka lebih mudah untuk menguji tanpa mock.Lihat juga artikel ini :
(Sebenarnya, Redux-saga seperti hibrida: aliran sangat penting tetapi efeknya deklaratif)
Kebingungan: tindakan / acara / perintah ...
Ada banyak kebingungan di dunia frontend tentang bagaimana beberapa konsep backend seperti CQRS / EventSourcing dan Flux / Redux mungkin terkait, sebagian besar karena di Flux kita menggunakan istilah "aksi" yang kadang-kadang dapat mewakili kode imperatif (
LOAD_USER
) dan peristiwa (USER_LOADED
). Saya percaya bahwa seperti event-sourcing, Anda hanya boleh mengirim acara.Menggunakan saga dalam praktik
Bayangkan sebuah aplikasi dengan tautan ke profil pengguna. Cara idiomatis untuk menangani ini dengan setiap middleware adalah:
redux-thunk
redux-saga
Kisah ini diterjemahkan menjadi:
Seperti yang Anda lihat, ada beberapa kelebihan
redux-saga
.Penggunaan
takeLatest
izin untuk menyatakan bahwa Anda hanya tertarik untuk mendapatkan data nama pengguna terakhir yang diklik (menangani masalah konkurensi jika pengguna mengklik sangat cepat pada banyak nama pengguna). Hal-hal semacam ini sulit dengan thunks. Anda bisa menggunakantakeEvery
jika Anda tidak ingin perilaku ini.Anda menjaga pembuat aksi tetap murni. Perhatikan bahwa masih berguna untuk menyimpan actionCreators (dalam kisah
put
dan komponendispatch
), karena ini dapat membantu Anda untuk menambahkan validasi tindakan (pernyataan / aliran / naskah naskah) di masa depan.Kode Anda menjadi jauh lebih dapat diuji karena efeknya deklaratif
Anda tidak perlu lagi memicu panggilan seperti rpc seperti
actions.loadUser()
. UI Anda hanya perlu mengirimkan apa yang TELAH TERJADI. Kami hanya memecat acara (selalu dalam bentuk lampau!) Dan bukan tindakan lagi. Ini berarti bahwa Anda dapat membuat "bebek" yang dipisahkan atau Konteks Terbatas dan bahwa saga dapat bertindak sebagai titik penghubung antara komponen-komponen modular ini.Ini berarti bahwa pandangan Anda lebih mudah dikelola karena mereka tidak perlu lagi memuat lapisan terjemahan antara apa yang telah terjadi dan apa yang seharusnya terjadi sebagai efek
Misalnya bayangkan tampilan gulir yang tak terbatas.
CONTAINER_SCROLLED
dapat menyebabkanNEXT_PAGE_LOADED
, tetapi apakah itu benar-benar tanggung jawab wadah yang dapat digulir untuk memutuskan apakah kita harus memuat halaman lain? Kemudian dia harus mengetahui hal-hal yang lebih rumit seperti apakah halaman terakhir berhasil dimuat atau tidak, atau apakah sudah ada halaman yang mencoba memuat, atau jika tidak ada lagi item yang tersisa untuk dimuat? Saya tidak berpikir begitu: untuk dapat digunakan kembali secara maksimal, wadah yang dapat digulir harus menggambarkan bahwa itu telah digulir. Pemuatan halaman adalah "efek bisnis" dari gulungan ituBeberapa mungkin berpendapat bahwa generator secara inheren dapat menyembunyikan keadaan di luar toko redux dengan variabel lokal, tetapi jika Anda mulai mengatur hal-hal kompleks di dalam thunks dengan memulai timer dll Anda akan memiliki masalah yang sama pula. Dan ada
select
efek yang sekarang memungkinkan untuk mendapatkan beberapa status dari toko Redux Anda.Sagas dapat dilalui dengan waktu dan juga memungkinkan pencatatan aliran yang rumit dan perangkat pengembangan yang saat ini sedang dikerjakan. Berikut adalah beberapa pendataan alur async sederhana yang sudah diterapkan:
Decoupling
Sagas tidak hanya menggantikan redux thunks. Mereka datang dari backend / sistem terdistribusi / event-sourcing.
Ini adalah kesalahpahaman yang sangat umum bahwa kisah-kisah hanya ada di sini untuk menggantikan redux thunks Anda dengan testability yang lebih baik. Sebenarnya ini hanyalah detail implementasi dari redux-saga. Menggunakan efek deklaratif lebih baik daripada thunks untuk testability, tetapi pola saga dapat diimplementasikan di atas kode imperatif atau deklaratif.
Pertama-tama, saga adalah bagian dari perangkat lunak yang memungkinkan untuk mengoordinasikan transaksi yang telah berjalan lama (konsistensi akhirnya), dan transaksi di berbagai konteks terbatas (jargon desain berbasis domain).
Untuk menyederhanakan ini untuk dunia frontend, bayangkan ada widget1 dan widget2. Ketika beberapa tombol pada widget1 diklik, maka itu akan memiliki efek pada widget2. Alih-alih menggabungkan 2 widget bersama-sama (yaitu widget1 mengirimkan tindakan yang menargetkan widget2), widget1 hanya mengirimkan bahwa tombolnya diklik. Kemudian hikayat mendengarkan tombol ini klik dan kemudian perbarui widget2 dengan membuang acara baru yang diketahui widget2.
Ini menambah tingkat tipuan yang tidak perlu untuk aplikasi sederhana, tetapi membuatnya lebih mudah untuk skala aplikasi yang kompleks. Anda sekarang dapat mempublikasikan widget1 dan widget2 ke repositori npm yang berbeda sehingga mereka tidak perlu tahu tentang satu sama lain, tanpa harus berbagi registri global tindakan. 2 widget tersebut sekarang dibatasi konteks yang dapat hidup secara terpisah. Mereka tidak membutuhkan satu sama lain untuk konsisten dan dapat digunakan kembali di aplikasi lain juga. Saga adalah titik penghubung antara dua widget yang mengoordinasikannya dengan cara yang berarti untuk bisnis Anda.
Beberapa artikel bagus tentang cara membuat struktur aplikasi Redux Anda, di mana Anda dapat menggunakan Redux-saga untuk alasan decoupling:
Sebuah usecase konkret: sistem notifikasi
Saya ingin komponen saya dapat memicu tampilan notifikasi dalam aplikasi. Tetapi saya tidak ingin komponen saya sangat digabungkan ke sistem pemberitahuan yang memiliki aturan bisnis sendiri (maks. 3 pemberitahuan ditampilkan pada saat yang sama, antrian pemberitahuan, waktu tampilan 4 detik dll ...).
Saya tidak ingin komponen JSX saya memutuskan kapan pemberitahuan akan ditampilkan / disembunyikan. Saya hanya memberikannya kemampuan untuk meminta pemberitahuan, dan meninggalkan aturan yang rumit di dalam saga. Hal-hal semacam ini cukup sulit diimplementasikan dengan pukulan atau janji.
Saya telah menjelaskan di sini bagaimana ini bisa dilakukan dengan saga
Mengapa itu disebut Saga?
Istilah saga berasal dari dunia backend. Saya awalnya memperkenalkan Yassine (penulis Redux-saga) untuk istilah itu dalam diskusi panjang .
Awalnya, istilah itu diperkenalkan dengan kertas , pola saga seharusnya digunakan untuk menangani konsistensi akhirnya dalam transaksi terdistribusi, tetapi penggunaannya telah diperluas ke definisi yang lebih luas oleh pengembang backend sehingga sekarang juga mencakup "manajer proses" pola (entah bagaimana pola kisah asli adalah bentuk khusus dari manajer proses).
Saat ini, istilah "saga" membingungkan karena dapat menggambarkan 2 hal yang berbeda. Seperti yang digunakan dalam redux-saga, itu tidak menjelaskan cara untuk menangani transaksi terdistribusi tetapi cara untuk mengoordinasikan tindakan di aplikasi Anda.
redux-saga
bisa juga dipanggilredux-process-manager
.Lihat juga:
Alternatif
Jika Anda tidak menyukai gagasan menggunakan generator tetapi Anda tertarik dengan pola saga dan sifat decouplingnya, Anda juga dapat mencapai hal yang sama dengan redux-observable yang menggunakan nama
epic
untuk menggambarkan pola yang sama persis, tetapi dengan RxJS. Jika Anda sudah terbiasa dengan Rx, Anda akan merasa seperti di rumah.Beberapa sumber daya yang berguna redux-saga
2017 menyarankan
yield put(someActionThunk)
jika itu masuk akal.Jika Anda takut menggunakan Redux-saga (atau Redux-observable) tetapi hanya perlu pola decoupling, periksa redux-dispatch-subscribe : itu memungkinkan untuk mendengarkan pengiriman dan memicu pengiriman baru di pendengar.
sumber
ADD_ITEM
, itu penting karena Anda mengirim tindakan yang bertujuan untuk memiliki efek pada toko Anda: Anda mengharapkan tindakan untuk melakukan sesuatu. Menjadi deklaratif merangkul filosofi pencarian-sumber acara: Anda tidak mengirim tindakan untuk memicu perubahan pada aplikasi Anda, tetapi Anda mengirim peristiwa di masa lalu untuk menggambarkan apa yang terjadi pada aplikasi Anda. Pengiriman acara harus cukup untuk mempertimbangkan bahwa keadaan aplikasi telah berubah. Fakta bahwa ada toko Redux yang bereaksi terhadap peristiwa adalah detail implementasi opsionalJawaban singkatnya : sepertinya pendekatan yang benar-benar masuk akal untuk masalah asinkroni bagi saya. Dengan beberapa peringatan.
Saya memiliki garis pemikiran yang sangat mirip ketika mengerjakan proyek baru yang baru kami mulai di pekerjaan saya. Saya adalah penggemar berat sistem elegan vanilla Redux untuk memperbarui toko dan komponen rerendering dengan cara yang tetap keluar dari nyali pohon komponen Bereaksi. Rasanya aneh bagi saya untuk menghubungkan ke
dispatch
mekanisme elegan untuk menangani asinkron.Saya akhirnya pergi dengan pendekatan yang sangat mirip dengan apa yang Anda miliki di perpustakaan saya faktor dari proyek kami, yang kami sebut react-redux-controller .
Saya akhirnya tidak akan pergi dengan pendekatan tepat yang Anda miliki di atas karena beberapa alasan:
dispatch
dirinya sendiri melalui ruang lingkup leksikal. Ini membatasi opsi untuk refactoring setelahconnect
pernyataan itu lepas kendali - dan itu terlihat sangat sulit hanya dengan satuupdate
metode itu. Jadi, Anda memerlukan beberapa sistem untuk memungkinkan Anda menyusun fungsi-fungsi dispatcher tersebut jika Anda memecahnya menjadi modul-modul terpisah.Secara bersamaan, Anda harus memasang beberapa sistem untuk memungkinkan
dispatch
dan toko untuk disuntikkan ke fungsi pengiriman Anda, bersama dengan parameter acara. Saya tahu tiga pendekatan yang masuk akal untuk injeksi ketergantungan ini:dispatch
pendekatan middleware lain , tapi saya berasumsi mereka pada dasarnya sama.connect
, daripada harus bekerja langsung dengan toko yang mentah dan dinormalisasi.this
konteks, melalui berbagai mekanisme yang mungkin.Memperbarui
Terlintas dalam benak saya bahwa sebagian dari teka-teki ini adalah batasan dari reaksi-reduks . Argumen pertama yang
connect
mendapatkan snapshot keadaan, tetapi tidak dikirim. Argumen kedua mendapatkan pengiriman tetapi bukan negara. Tidak ada argumen yang mendapatkan pukulan yang menutup kondisi saat ini, karena dapat melihat status yang diperbarui pada saat kelanjutan / panggilan balik.sumber
Tujuan Abramov - dan idealnya semua orang - hanya untuk merangkum kompleksitas (dan panggilan async) di tempat yang paling tepat .
Di mana tempat terbaik untuk melakukannya dalam aliran data Redux standar? Bagaimana tentang:
sumber
Untuk menjawab pertanyaan yang ditanyakan di awal:
Perlu diingat bahwa dokumen itu untuk Redux, bukan Redux plus Bereaksi. Toko Redux yang terhubung dengan React components dapat melakukan apa yang Anda katakan, tetapi toko Plain Jane Redux tanpa middleware tidak menerima argumen
dispatch
kecuali objek biasa.Tanpa middleware tentu saja Anda masih bisa melakukannya
Tapi itu kasus serupa di mana asynchrony dibungkus sekitar Redux bukan ditangani oleh Redux. Jadi, middleware memungkinkan untuk sinkronisasi dengan memodifikasi apa yang dapat diteruskan langsung ke
dispatch
.Yang mengatakan, semangat saran Anda, saya pikir, valid. Pasti ada cara lain Anda bisa menangani asinkron dalam aplikasi Redux + Bereaksi.
Salah satu manfaat menggunakan middleware adalah Anda dapat terus menggunakan pembuat tindakan seperti biasa tanpa khawatir bagaimana mereka terhubung. Misalnya, menggunakan
redux-thunk
, kode yang Anda tulis akan sangat miripyang tidak terlihat jauh berbeda dari aslinya - hanya sedikit dikocok - dan
connect
tidak tahu ituupdateThing
(atau perlu) asinkron.Jika Anda juga ingin mendukung janji , yang dapat diobservasi , kisah-kisah , atau kebiasaan gila dan pembuat tindakan yang sangat deklaratif , maka Redux dapat melakukannya hanya dengan mengubah apa yang Anda sampaikan
dispatch
(alias, apa yang Anda kembalikan dari pembuat tindakan). Tidak perlu melakukan mucking dengan komponen Bereaksi (atauconnect
panggilan).sumber
OK, mari kita mulai melihat bagaimana middleware bekerja terlebih dahulu, yang cukup menjawab pertanyaan, ini adalah kode sumber fungsi pplyMiddleWare di Redux:
Lihat bagian ini, lihat bagaimana pengiriman kami menjadi suatu fungsi .
OK, inilah bagaimana Redux-thunk sebagai salah satu middlewares yang paling banyak digunakan untuk Redux memperkenalkan dirinya:
Jadi seperti yang Anda lihat, itu akan mengembalikan fungsi alih-alih tindakan, berarti Anda dapat menunggu dan memanggilnya kapan saja karena itu fungsi ...
Jadi apa-apaan ini? Begitulah diperkenalkan di Wikipedia:
Jadi lihat betapa mudahnya konsep itu dan bagaimana itu dapat membantu Anda mengelola tindakan async Anda ...
Itu sesuatu yang bisa Anda jalani tanpanya, tetapi ingat dalam pemrograman selalu ada cara yang lebih baik, lebih rapi, dan tepat untuk melakukan sesuatu ...
sumber
Untuk menggunakan Redux-saga adalah middleware terbaik dalam implementasi React-redux.
Mis .: store.js
Dan kemudian saga.js
Dan kemudian action.js
Dan kemudian reducer.js
Dan kemudian main.js
coba ini .. sudah berfungsi
sumber
Ada pembuat tindakan yang sinkron dan kemudian ada pembuat tindakan yang tidak sinkron.
Pembuat tindakan sinkron adalah yang ketika kami menyebutnya, ia segera mengembalikan objek Tindakan dengan semua data yang relevan yang melekat pada objek itu dan siap untuk diproses oleh reduksi kami.
Pembuat aksi asinkron adalah pembuat yang membutuhkan sedikit waktu sebelum siap untuk akhirnya mengirim tindakan.
Menurut definisi, kapan saja Anda memiliki pembuat tindakan yang membuat permintaan jaringan, itu selalu akan memenuhi syarat sebagai pembuat tindakan async.
Jika Anda ingin memiliki pembuat tindakan asinkron di dalam aplikasi Redux Anda harus menginstal sesuatu yang disebut middleware yang akan memungkinkan Anda untuk berurusan dengan pembuat tindakan asinkron tersebut.
Anda dapat memverifikasi ini dalam pesan kesalahan yang memberitahu kami menggunakan middleware khusus untuk tindakan async.
Jadi apa itu middleware dan mengapa kita membutuhkannya untuk aliran async di Redux?
Dalam konteks redux middleware seperti redux-thunk, middleware membantu kita berurusan dengan pembuat aksi asinkron karena itu adalah sesuatu yang Redux tidak bisa menangani di luar kotak.
Dengan middleware yang diintegrasikan ke dalam siklus Redux, kami masih memanggil pembuat tindakan, yang akan mengembalikan tindakan yang akan dikirim tetapi sekarang ketika kami mengirimkan tindakan, daripada mengirimkannya langsung ke semua reduksi kami, kami akan untuk mengatakan bahwa suatu tindakan akan dikirim melalui semua middleware yang berbeda di dalam aplikasi.
Di dalam aplikasi Redux tunggal, kita dapat memiliki middleware sebanyak atau sesedikit yang kita inginkan. Sebagian besar, dalam proyek yang kami kerjakan kami akan memiliki satu atau dua middleware yang terhubung ke toko Redux kami.
Middleware adalah fungsi JavaScript biasa yang akan dipanggil dengan setiap tindakan yang kami kirim. Di dalam fungsi itu, middleware memiliki kesempatan untuk menghentikan tindakan agar tidak dikirim ke salah satu reduksi, itu dapat memodifikasi tindakan atau hanya bermain-main dengan tindakan dengan cara apa pun yang Anda misalnya, kita bisa membuat middleware yang konsol log setiap tindakan yang Anda kirimkan hanya untuk kesenangan menonton Anda.
Ada sejumlah besar middleware open source yang dapat Anda instal sebagai dependensi ke dalam proyek Anda.
Anda tidak terbatas hanya menggunakan middleware open source atau menginstalnya sebagai dependensi. Anda dapat menulis middleware kustom Anda sendiri dan menggunakannya di dalam toko Redux Anda.
Salah satu kegunaan middleware yang lebih populer (dan mendapatkan jawaban Anda) adalah untuk berurusan dengan pembuat tindakan asinkron, mungkin middleware paling populer di luar sana adalah redux-thunk dan ini tentang membantu Anda berurusan dengan pembuat tindakan asinkron.
Ada banyak jenis middleware lain yang juga membantu Anda dalam berurusan dengan pembuat tindakan asinkron.
sumber
Untuk Menjawab pertanyaan:
Saya akan mengatakan setidaknya untuk dua alasan:
Alasan pertama adalah pemisahan kekhawatiran, itu bukan tugas
action creator
untuk memanggilapi
dan mendapatkan data kembali, Anda harus melewati dua argumen untuk Andaaction creator function
,action type
dan apayload
.Alasan kedua adalah karena
redux store
menunggu objek polos dengan jenis tindakan wajib dan opsional apayload
(tapi di sini Anda harus melewati payload juga).Pembuat tindakan harus berupa objek biasa seperti di bawah ini:
Dan pekerjaan
Redux-Thunk midleware
untukdispache
hasil Andaapi call
sesuaiaction
.sumber
Ketika bekerja di proyek perusahaan, ada banyak persyaratan yang tersedia di perangkat tengah seperti (saga) tidak tersedia dalam aliran asinkron sederhana, di bawah ini adalah beberapa:
Daftarnya panjang, cukup tinjau bagian lanjutan dalam dokumentasi saga
sumber