Saya baru mengenal React / Redux. Saya menggunakan middleware fetch api di aplikasi Redux untuk memproses API. Ini ( redux-api-middleware ). Saya pikir ini adalah cara yang baik untuk memproses tindakan api asinkron. Tetapi saya menemukan beberapa kasus yang tidak dapat diselesaikan sendiri.
Seperti yang dikatakan beranda ( Lifecycle ), siklus hidup API pengambilan dimulai dengan pengiriman tindakan CALL_API diakhiri dengan pengiriman tindakan FSA.
Jadi kasus pertama saya menunjukkan / menyembunyikan prapemuat saat mengambil API. Middleware akan mengirimkan tindakan FSA di awal dan mengirimkan tindakan FSA di akhir. Kedua tindakan tersebut diterima oleh pereduksi yang seharusnya hanya melakukan beberapa pemrosesan data normal. Tidak ada operasi UI, tidak ada lagi operasi. Mungkin saya harus menyimpan status pemrosesan dalam keadaan lalu merendernya saat menyimpan pembaruan.
Tapi bagaimana melakukan ini? Komponen reaksi mengalir di seluruh halaman? apa yang terjadi dengan pembaruan toko dari tindakan lain? Maksud saya, mereka lebih seperti peristiwa daripada negara!
Bahkan kasus yang lebih buruk, apa yang harus saya lakukan ketika saya harus menggunakan dialog konfirmasi asli atau dialog peringatan di aplikasi redux / react? Di mana mereka harus ditempatkan, tindakan atau pengurang?
Semoga sukses! Berharap untuk membalas.
sumber
Jawaban:
Saya tidak akan mengatakannya. Saya pikir indikator pemuatan adalah contoh bagus dari UI yang dengan mudah dijelaskan sebagai fungsi dari negara: dalam hal ini, dari variabel boolean. Meskipun jawaban ini benar, saya ingin memberikan beberapa kode untuk menyertainya.
Dalam
async
contoh di repo Redux , peredam memperbarui bidang yang disebutisFetching
:Komponen menggunakan
connect()
dari React Redux untuk berlangganan status toko dan mengembalikanisFetching
sebagai bagian dari nilaimapStateToProps()
pengembalian sehingga tersedia di props komponen yang terhubung:Terakhir, komponen menggunakan
isFetching
prop dalamrender()
fungsi tersebut untuk merender label "Memuat ..." (yang dapat dianggap sebagai pemintal):Efek samping apa pun (dan menampilkan dialog pasti merupakan efek samping) tidak termasuk dalam pereduksi. Pikirkan pereduksi sebagai "pembangun negara" pasif. Mereka tidak benar-benar "melakukan" sesuatu.
Jika Anda ingin menunjukkan peringatan, lakukan ini dari komponen sebelum mengirimkan tindakan, atau lakukan ini dari pembuat tindakan. Pada saat suatu tindakan dikirim, sudah terlambat untuk melakukan efek samping sebagai tanggapannya.
Untuk setiap aturan, ada pengecualian. Terkadang logika efek samping Anda begitu rumit sehingga Anda benar - benar ingin memasangkannya ke jenis tindakan tertentu atau ke pereduksi tertentu. Dalam hal ini, periksa proyek lanjutan seperti Redux Saga dan Redux Loop . Lakukan ini hanya jika Anda merasa nyaman dengan vanilla Redux dan memiliki masalah nyata dengan efek samping yang tersebar yang ingin Anda buat lebih mudah dikelola.
sumber
Promise.all
menjadi satu promise dan kemudian mengirimkan satu tindakan untuk semua pengambilan. Atau Anda harus mempertahankan banyakisFetching
variabel di negara bagian Anda.isFetching
bendera. Ini disetel untuk setiap set objek yang sedang diambil. Anda dapat menggunakan komposisi peredam untuk mengimplementasikannya.RECEIVE_POSTS
tidak pernah terpicu, tanda pemuatan akan tetap ada kecuali Anda telah membuat semacam batas waktu untuk menampilkanerror loading
pesan.Jawaban bagus Dan Abramov! Hanya ingin menambahkan bahwa saya melakukan kurang lebih persis seperti itu di salah satu aplikasi saya (menyimpan isFetching sebagai boolean) dan akhirnya harus menjadikannya integer (yang akhirnya membaca sebagai jumlah permintaan yang belum diselesaikan) untuk mendukung beberapa secara bersamaan permintaan.
dengan boolean:
permintaan 1 dimulai -> pemintal aktif -> permintaan 2 dimulai -> permintaan 1 berakhir -> pemintal mati -> permintaan 2 berakhir
dengan integer:
permintaan 1 dimulai -> pemintal aktif -> permintaan 2 dimulai -> permintaan 1 berakhir -> permintaan 2 berakhir -> pemintal mati
sumber
isFetching
bendera. Jika Anda melihat lebih dekat pada contoh yang saya tautkan, Anda akan melihat bahwa tidak ada satu objekisFetched
tetapi banyak: satu per subreddit (yang diambil dalam contoh itu).fetchCounter
untuk beberapa progress bar di bagian atas layar dan beberapa spesifikisFetching
bendera untuk daftar dan halaman.Saya ingin menambahkan sesuatu. Contoh dunia nyata menggunakan bidang
isFetching
di toko untuk mewakili saat koleksi item sedang diambil. Setiap koleksi digeneralisasikan kepagination
peredam yang dapat dihubungkan ke komponen Anda untuk melacak status dan menunjukkan apakah koleksi sedang dimuat.Kebetulan saya ingin mengambil detail untuk entitas tertentu yang tidak sesuai dengan pola penomoran halaman. Saya ingin memiliki status yang mewakili jika detail diambil dari server tetapi juga saya tidak ingin memiliki peredam hanya untuk itu.
Untuk mengatasi ini saya menambahkan peredam umum lain yang disebut
fetching
. Ini bekerja dengan cara yang mirip dengan peredam pagination dan tanggung jawabnya hanya untuk menonton serangkaian tindakan dan menghasilkan status baru dengan pasangan[entity, isFetching]
. Itu memungkinkanconnect
peredam ke komponen apa pun dan untuk mengetahui apakah aplikasi saat ini mengambil data tidak hanya untuk koleksi tetapi untuk entitas tertentu.sumber
Saya belum pernah mendengar pertanyaan ini sampai sekarang, tetapi karena tidak ada jawaban yang diterima, saya akan angkat topi. Saya menulis alat untuk pekerjaan ini: react-loader-factory . Ada lebih banyak hal yang terjadi daripada solusi Abramov, tetapi lebih modular dan nyaman, karena saya tidak ingin berpikir setelah saya menulisnya.
Ada empat bagian besar:
const loaderWrapper = loaderFactory(actionsList, monitoredStates);
connect()
dikembalikan di Redux), sehingga Anda bisa langsung memasangnya ke barang yang sudah ada.const LoadingChild = loaderWrapper(ChildComponent);
ACTION_SUCCESS
danACTION_REQUEST
, misalnya). (Anda dapat mengirimkan tindakan di tempat lain dan hanya memantau dari bungkusnya jika Anda mau, tentu saja.)Modul itu sendiri tidak bergantung pada redux-api-middleware, tetapi itulah yang saya gunakan dengannya, jadi inilah beberapa contoh kode dari README:
Komponen dengan Loader yang membungkusnya:
Peredam untuk Loader untuk memonitor (meskipun Anda dapat menghubungkannya secara berbeda jika Anda mau):
Saya berharap dalam waktu dekat saya akan menambahkan hal-hal seperti batas waktu dan kesalahan ke modul, tetapi polanya tidak akan jauh berbeda.
Jawaban singkat untuk pertanyaan Anda adalah:
sumber
Apakah saya satu-satunya yang berpikir bahwa indikator pemuatan tidak termasuk dalam toko Redux? Maksud saya, menurut saya itu bukan bagian dari status aplikasi itu sendiri ..
Sekarang, saya bekerja dengan Angular2, dan yang saya lakukan adalah saya memiliki layanan "Memuat" yang memperlihatkan indikator pemuatan yang berbeda melalui RxJS BehaviourSubjects .. Saya kira mekanismenya sama, saya hanya tidak menyimpan informasi di Redux.
Pengguna LoadingService hanya berlangganan ke acara yang ingin mereka dengarkan ..
Pencipta tindakan Redux saya memanggil LoadingService setiap kali ada hal yang perlu diubah. Komponen UX berlangganan observable yang diekspos ...
sumber
Anda dapat menambahkan pendengar perubahan ke toko Anda, baik menggunakan
connect()
dari React Redux ataustore.subscribe()
metode tingkat rendah . Anda harus memiliki indikator pemuatan di toko Anda, yang kemudian dapat diperiksa oleh penangan perubahan toko dan memperbarui status komponen. Komponen kemudian merender prapemuat jika diperlukan, berdasarkan status.alert
danconfirm
seharusnya tidak menjadi masalah. Mereka memblokir dan memperingatkan bahkan tidak menerima masukan apa pun dari pengguna. Denganconfirm
, Anda dapat menyetel status berdasarkan apa yang diklik pengguna jika pilihan pengguna memengaruhi rendering komponen. Jika tidak, Anda dapat menyimpan pilihan sebagai variabel anggota komponen untuk digunakan nanti.sumber
addNofication(message)
. Kasus lainnya adalah prapemuat yang juga disediakan oleh aplikasi asli host dan dipicu oleh API javascriptnya. Saya menambahkan pembungkus untuk api tersebut, dicomponentDidUpdate
dalam komponen React. Bagaimana cara mendesain props atau status komponen ini?Kami memiliki tiga jenis notifikasi di aplikasi kami, yang semuanya dirancang sebagai aspek:
Ketiganya berada di level teratas aplikasi kami (Utama), dan dihubungkan melalui Redux seperti yang ditunjukkan pada cuplikan kode di bawah ini. Alat peraga ini mengontrol tampilan dari aspek yang sesuai.
Saya merancang proxy yang menangani semua panggilan API kami, sehingga semua kesalahan isFetching dan (api) dimediasi dengan actionCreators yang saya impor di proxy. (Selain itu, saya juga menggunakan webpack untuk menyuntikkan tiruan layanan dukungan untuk dev sehingga kami dapat bekerja tanpa ketergantungan server.)
Tempat lain dalam aplikasi yang perlu menyediakan jenis notifikasi apa pun hanya mengimpor tindakan yang sesuai. Snackbar & Error memiliki parameter untuk menampilkan pesan.
) ekspor kelas default Main extends React.Component {
sumber
Saya menyimpan url seperti ::
Dan kemudian saya memiliki pemilih yang dihafal (melalui pemilihan ulang).
Untuk membuat url unik dalam kasus POST, saya meneruskan beberapa variabel sebagai kueri.
Dan di mana saya ingin menunjukkan indikator, saya cukup menggunakan variabel getFetchCount
sumber
Object.keys(items).filter(item => items[item] === true).length > 0 ? true : false
denganObject.keys(items).every(item => items[item])
cara.some
bukanevery
, tapi ya, terlalu banyak perbandingan yang tidak diperlukan dalam solusi yang diusulkan pertama.Object.entries(items).some(([url, fetching]) => fetching);