Redux - beberapa toko, mengapa tidak?

221

Sebagai catatan: Saya telah membaca dokumen untuk Redux (Baobab, juga), dan saya telah melakukan bagian yang adil dari Googling & testing.

Mengapa sangat disarankan bahwa aplikasi Redux hanya memiliki satu toko?

Saya memahami pro / kontra dari pengaturan satu toko vs beberapa pengaturan toko ( Ada banyak T&J di SO tentang hal ini ).

IMO, keputusan arsitektur ini adalah milik pengembang aplikasi berdasarkan kebutuhan proyek mereka. Jadi mengapa sangat disarankan untuk Redux, hampir sampai terdengar wajib ( meskipun tidak ada yang menghentikan kita dari membuat banyak toko )?

EDIT: umpan balik setelah mengonversi ke satu toko

Setelah beberapa bulan bekerja dengan redux pada apa yang banyak orang anggap sebagai SPA kompleks, saya dapat mengatakan bahwa struktur toko tunggal telah menjadi kesenangan murni untuk bekerja dengannya.

Beberapa poin yang mungkin membantu orang lain memahami mengapa satu toko vs banyak toko adalah pertanyaan yang bisa diperdebatkan dalam banyak kasus penggunaan:

  • itu dapat diandalkan : kami menggunakan penyeleksi untuk menggali status aplikasi dan mendapatkan informasi yang relevan dengan konteks. Kita tahu bahwa semua data yang dibutuhkan ada dalam satu toko. Ini menghindari semua pertanyaan tentang di mana masalah negara bisa terjadi.
  • itu cepat : toko kami saat ini memiliki hampir 100 reduksi, jika tidak lebih. Bahkan pada hitungan itu, hanya sedikit reduksi yang memproses data pada pengiriman yang diberikan, yang lain hanya mengembalikan keadaan sebelumnya. Argumen bahwa toko besar / kompleks ( nbr reducers ) lambat cukup banyak diperdebatkan. Setidaknya kami belum melihat adanya masalah kinerja yang berasal dari sana.
  • ramah debugging : sementara ini adalah argumen paling meyakinkan untuk menggunakan redux secara keseluruhan, itu juga berlaku untuk satu toko vs beberapa toko. Saat membuat aplikasi Anda pasti memiliki kesalahan status dalam proses ( kesalahan pemrogram ), itu normal. PITA adalah saat kesalahan tersebut membutuhkan waktu berjam-jam untuk debug. Berkat satu toko ( dan redux-logger ) kami tidak pernah menghabiskan lebih dari beberapa menit untuk masalah negara yang diberikan.

beberapa petunjuk

Tantangan sebenarnya dalam membangun toko redux Anda adalah ketika memutuskan bagaimana menyusunnya . Pertama, karena mengubah struktur di jalan hanyalah rasa sakit yang besar. Kedua, karena sebagian besar menentukan bagaimana Anda akan menggunakan, dan menanyakan data aplikasi Anda untuk proses apa pun. Ada banyak saran tentang cara membuat struktur toko. Dalam kasus kami, kami menemukan yang berikut ini ideal:

{
  apis: {     // data from various services
    api1: {},
    api2: {},
    ...
  }, 
  components: {} // UI state data for each widget, component, you name it 
  session: {} // session-specific information
}

Semoga umpan balik ini akan membantu orang lain.

EDIT 2 - alat bantu toko

Bagi Anda yang telah bertanya-tanya bagaimana cara "dengan mudah" mengelola satu toko , yang dapat dengan cepat menjadi rumit. Ada alat yang membantu mengisolasi dependensi / logika struktural toko Anda.

Ada Normalizr yang menormalkan data Anda berdasarkan skema. Itu kemudian menyediakan antarmuka untuk bekerja dengan data Anda dan mengambil bagian lain dari data Anda dengan id, seperti Kamus.

Tidak mengenal Normalizr pada saat itu, saya membangun sesuatu di sepanjang jalur yang sama. relational-json mengambil skema, dan mengembalikan antarmuka berbasis Tabel ( sedikit seperti database ). Keuntungan dari relational-json adalah bahwa struktur data Anda secara dinamis mereferensikan bagian lain dari data Anda ( pada dasarnya, Anda dapat melintasi data Anda ke segala arah, sama seperti objek JS normal ). Ini tidak setua Normalizr, tetapi saya telah menggunakannya dengan sukses dalam produksi selama beberapa bulan sekarang.

Sebastien Daniel
sumber
4
Saya suka pendekatan Anda untuk struktur toko yang Anda gunakan; namun, bagaimana Anda menangani pemetaan perubahan keadaan api ke perubahan status komponen Anda? Jadi katakanlah saya menerima data spesifik domain dari API saya, bagaimana ini diterjemahkan ke struktur data umum yang akan ditemukan di komponen saya?
Diniden
Bagaimana komponen Anda memetakan / menggunakan data toko terserah Anda, sungguh. Meskipun saya pikir saya tidak sepenuhnya memahami pertanyaan Anda, bisakah Anda menguraikan atau memulai sesi obrolan?
Sebastien Daniel
2
Saya kira pertanyaannya adalah: apakah komponen Anda membuat apa pun dari status apis, atau apakah mereka hanya membuat apa pun yang dimasukkan ke dalam status komponen. Saya akan curiga jika Anda HANYA render membuat dari keadaan komponen, maka Anda telah menemukan cara terbaik untuk membuat komponen dan Wadah Anda sangat dapat digunakan kembali bahkan di hadapan data spesifik domain. Jika komponen Anda merender sebagian dari keadaan API DAN keadaan komponen, maka saya kira Anda menggunakan Wadah khusus Domain untuk memetakan data di apis ke daftar umum dan primitif yang dipahami komponen Anda.
Diniden
2
Saya menggunakan Redux dalam hubungannya dengan penyeleksi, yang pada dasarnya memoize-murni pemetaan data. Setiap komponen "bereaksi" untuk menyimpan pembaruan, dan jika suatu perubahan relevan dengan itu, itu "memilih" data dan merender sesuai. Jadi ya, komponen HANYA di-render berdasarkan apa yang penting bagi mereka. Tapi itu bukan hanya karena Redux atau struktur toko. Ini karena kombinasi dari penyimpanan data yang tidak dapat diubah, uji perbandingan referensial untuk perubahan data, dan pemilih murni yang mengambil data yang dibutuhkan komponen, dalam format yang dibutuhkannya.
Sebastien Daniel
Hai @SebastienDaniel, dapatkah Anda menunjukkan contoh bagaimana Anda menerapkan pemeriksaan yang dilakukan setiap komponen untuk mengetahui apakah perubahan dalam pembaruan toko relevan dengan itu? Maksud saya jika Anda menggunakan semacam pola umum ... atau jika dalam setiap kasus tertentu Anda memeriksa apakah data terkait komponen tertentu telah berubah.
John Bernardsson

Jawaban:

232

Ada kasus tepi ketika Anda mungkin menggunakan beberapa toko (misalnya jika Anda memiliki masalah kinerja dengan memperbarui daftar ribuan item yang ada di layar pada waktu yang sama berkali-kali per detik). Yang mengatakan itu pengecualian dan di sebagian besar aplikasi Anda tidak perlu lebih dari satu toko.

Mengapa kami menekankan hal ini dalam dokumen? Karena kebanyakan orang yang berasal dari latar belakang Flux akan menganggap banyak toko adalah solusi untuk membuat pembaruan kode modular. Namun Redux memiliki solusi berbeda untuk ini: komposisi peredam.

Memiliki beberapa reducers yang selanjutnya dipecah menjadi pohon reducer adalah cara Anda menjaga pembaruan modular di Redux. Jika Anda tidak mengenali ini dan pergi ke beberapa toko tanpa terlebih dahulu memahami komposisi peredam, Anda akan kehilangan banyak manfaat dari arsitektur toko tunggal Redux:

  • Menggunakan komposisi peredam membuatnya mudah untuk menerapkan "pembaruan bergantung" ala waitForFlux dengan menulis peredam yang secara manual memanggil peredam lain dengan informasi tambahan dan dalam urutan tertentu.

  • Dengan satu toko, sangat mudah untuk bertahan, melembabkan, dan membaca keadaan. Server rendering dan prefetching data adalah sepele karena hanya ada satu penyimpanan data yang perlu diisi dan direhidrasi pada klien, dan JSON dapat mendeskripsikan isinya tanpa khawatir tentang ID atau nama toko.

  • Satu toko memungkinkan fitur perjalanan waktu Redux DevTools. Itu juga membuat ekstensi komunitas seperti redux-undo atau redux-optimist mudah karena mereka beroperasi pada tingkat peredam. "Peningkat peredam" seperti itu tidak dapat ditulis untuk toko.

  • Satu toko menjamin bahwa langganan dipanggil hanya setelah pengiriman diproses. Artinya, pada saat pendengar diberi tahu, negara telah sepenuhnya diperbarui. Dengan banyak toko, tidak ada jaminan seperti itu. Ini adalah salah satu alasan Flux membutuhkan waitFortongkat penyangga. Dengan satu toko, ini bukan masalah yang Anda lihat di tempat pertama.

  • Yang terpenting, banyak toko tidak diperlukan di Redux (kecuali untuk kasus tepi kinerja yang harus Anda profil terlebih dahulu). Kami menjadikannya poin penting dalam dokumen sehingga Anda didorong untuk mempelajari komposisi peredam dan pola Redux lainnya alih-alih menggunakan Redux seolah-olah itu Flux, dan kehilangan manfaatnya.

Dan Abramov
sumber
11
Saya akui saya tidak mengerti keuntungan penuh / perlunya komposisi peredam. Berkat jawaban Anda, saya melakukan lebih banyak bacaan dan contoh (TodoMVC, lagi). Dengan contoh sekecil itu, sulit untuk memahami peningkatan aktual yang diberikan oleh komposisi peredam. Namun, dengan sedikit pemikiran, dalam skala besar keuntungannya (sekarang) jelas. Terima kasih sekali lagi, jawaban yang bagus!
Sebastien Daniel
4
@Sebastien Contoh "shopping cart" lebih baik untuk ini.
Dan Abramov
3
Saya perlahan menerapkan redux ke aplikasi tradisional (non SPA). Saya menggunakan toko multilpe untuk setiap "keseluruhan" yang saya konversi menjadi implementasi react / redux sampai seluruh aplikasi dapat dimodifikasi untuk menggunakan toko yang sama.
Paul Knopf
5
@DanAbramov Ingin tahu apa pendapat Anda tentang situasi di mana Anda memiliki "aplikasi" utama yang menjalankan toko Redux sendiri dan mengimpor melalui npm "aplikasi" mandiri yang menjalankan toko Redux sendiri yang terpisah. Misalnya, jika salah satu tim lain di perusahaan Anda memiliki semacam layanan perpesanan dengan UI yang ingin Anda tarik tanpa mencemari toko Anda dengan data itu.
natlee75
6
@ natlee75 "Beberapa alasan yang sah untuk menggunakan beberapa toko di Redux mungkin termasuk: [...] Mengisolasi aplikasi Redux sebagai komponen dalam aplikasi yang lebih besar, dalam hal ini Anda mungkin ingin membuat toko per instance komponen root." Dari redux.js.org/docs/FAQ.html#store-setup-multiple-stores
Kevin
24

Dalam beberapa aplikasi perusahaan yang sangat besar dengan ratusan atau ribuan reduksi, sering kali berguna untuk memikirkan berbagai area aplikasi sebagai aplikasi yang sepenuhnya terpisah. Dalam kasus tersebut (di mana itu sebenarnya adalah beberapa aplikasi yang berbagi nama domain), saya menggunakan beberapa toko.

Misalnya, saya cenderung memperlakukan area fungsi umum berikut sebagai aplikasi terpisah:

  • Admin
  • Analytics / data vis dasbor
  • Manajemen penagihan & arus pembelian
  • Tim akun perusahaan / manajemen izin

Jika ada yang kecil, simpan saja sebagai bagian dari aplikasi utama. Jika mereka tumbuh sangat besar (seperti beberapa alat manajemen & analitik akun perusahaan), bagilah.

Cara terbaik untuk mengelola aplikasi yang sangat besar adalah memperlakukannya seperti komposisi banyak aplikasi yang lebih kecil.

Jika aplikasi Anda kurang dari mengatakan ~ 50k LOC, Anda mungkin harus mengabaikan saran ini dan sebagai gantinya mengikuti saran Dan.

Jika aplikasi Anda lebih dari 1 Juta LOC, Anda mungkin harus memisahkan aplikasi mini, bahkan jika Anda mempertahankannya dalam mono repo.

Eric Elliott
sumber
5

Keputusan arsitektur ini adalah milik pengembang aplikasi berdasarkan kebutuhan proyek mereka

Anda hidup di dunia Anda sendiri. Saya bertemu dengan orang-orang yang menggunakan redux, karena itu populer, setiap hari. Anda bahkan tidak bisa membayangkan berapa banyak proyek yang mulai reduxing tanpa keputusan. Saya benci pendekatan redux tetapi harus menggunakannya, karena pengembang lain tidak tahu apa-apa lagi. Itu hanya gelembung epik yang dipompa oleh facebook.

  • Itu tidak dapat diandalkan karena bagian-bagian toko tidak terisolasi.
  • Ini tidak efisien karena Anda mengkloning dan melintasi hash trie. Ketika mutasi tumbuh secara hitung - kompleksitas tumbuh secara geometris. Anda tidak dapat memperbaikinya dengan refactoring reduksi, penyeleksi, dll. Anda harus membagi trie Anda.
  • Ketika menjadi lambat tidak ada yang ingin membaginya menjadi aplikasi terpisah dengan toko yang terpisah. Tidak ada yang mau menghabiskan uang untuk refactoring. Orang-orang biasanya mengubah beberapa komponen pintar menjadi dump dan hanya itu. Apakah Anda tahu masa depan apa yang sedang menunggu pengembang redux? Mereka akan memelihara neraka ini.
  • Itu tidak ramah debugging . Sulit untuk men-debug koneksi antara bagian-bagian toko yang hampir terisolasi. Sangat sulit bahkan untuk menganalisis jumlah koneksi ini.

Bayangkan Anda memiliki beberapa toko redux. Anda akan memutus aliran data searah. Anda akan segera menyadari betapa banyak koneksi antar toko yang Anda miliki. Anda dapat menderita dari koneksi ini, berkelahi dengan deps melingkar, dll.

Toko abadi tunggal dengan aliran searah bukanlah ramuan untuk setiap penyakit. Jika Anda tidak ingin mempertahankan arsitektur proyek, Anda akan tetap menderita.

puchu
sumber
Saya menyukai apa yang Anda katakan, dan di sini saya menanyakan pertanyaan terkait hal ini. Maukah Anda melihat ini ketika mendapatkan waktu dan membagikan pendapat Anda? Pertanyaan yang saya ajukan di Reddit, karena SO tidak mendorong pertanyaan seperti itu di sini.
Arup Rakshit
3

Beberapa toko dapat membantu dalam kasus penggunaan berikut 1. Jika Anda memiliki komponen besar yang tidak tergantung satu sama lain dalam hal struktur data, perilaku, konteks aplikasi. Mengisolasi komponen-komponen ini memudahkan mengelola data dan aliran aplikasi Anda. Ini juga membantu pengembangan dan pemeliharaan komponen Anda secara independen. 2. Masalah kinerja: bukan kasus penggunaan biasa, tetapi jika beberapa komponen Anda memperbarui sangat sering dan tidak berdampak pada komponen lain, mungkin Anda bisa pergi ke toko yang berbeda.

Untuk semua kasus lain, Anda mungkin tidak perlu memiliki beberapa toko. Seperti kata Dan, menciptakan komposisi peredam yang matang dapat terbukti menjadi solusi yang lebih baik.

newtonflash
sumber
Pesan Anda sepertinya "selalu gunakan redux kecuali beberapa case" == "Anda tidak perlu arsitektur proyek kecuali beberapa case". Sangat dekat dengan kenyataan, saya senang.
puchu
2

mengapa kita tidak dapat menggunakan beberapa toko menggunakan redux ????

Ini tidak diperlukan di Redux karena pemisahan antara domain data sudah dicapai dengan memecah satu peredam menjadi pengecil yang lebih kecil.


Bisakah atau haruskah saya membuat beberapa toko? Bisakah saya mengimpor toko saya secara langsung, dan menggunakannya dalam komponen sendiri?

Pola Flux asli menggambarkan memiliki beberapa "toko" di suatu aplikasi, masing-masing memegang area data domain yang berbeda. Ini dapat menimbulkan masalah seperti perlu memiliki satu toko "tunggu" toko lain untuk diperbarui.

Ini tidak diperlukan di Redux karena pemisahan antara domain data sudah dicapai dengan memecah satu peredam menjadi pengecil yang lebih kecil.

Seperti dengan beberapa pertanyaan lain, dimungkinkan untuk membuat beberapa toko Redux yang berbeda dalam satu halaman, tetapi pola yang dimaksud adalah hanya memiliki satu toko. Memiliki satu toko memungkinkan penggunaan Redux DevTools, membuat data yang bertahan lama dan lebih sederhana, dan menyederhanakan logika berlangganan.

Beberapa alasan yang sah untuk menggunakan beberapa toko di Redux mungkin termasuk:

Memecahkan masalah kinerja yang disebabkan oleh pembaruan yang terlalu sering di beberapa bagian negara bagian, ketika dikonfirmasi dengan membuat profil aplikasi. Mengisolasi aplikasi Redux sebagai komponen dalam aplikasi yang lebih besar, dalam hal ini Anda mungkin ingin membuat toko per instance komponen root. Namun, membuat toko baru tidak harus menjadi insting pertama Anda, terutama jika Anda berasal dari latar belakang Flux. Coba komposisi peredam terlebih dahulu, dan hanya gunakan beberapa toko jika tidak menyelesaikan masalah Anda.

Demikian pula, sementara Anda dapat mereferensikan instance toko Anda dengan mengimpornya secara langsung, ini bukan pola yang disarankan di Redux. Jika Anda membuat turunan toko dan mengekspornya dari modul, itu akan menjadi singleton. Ini berarti akan lebih sulit untuk mengisolasi aplikasi Redux sebagai komponen dari aplikasi yang lebih besar, jika ini diperlukan, atau untuk mengaktifkan rendering server, karena pada server Anda ingin membuat instance toko terpisah untuk setiap permintaan.

dokumen resmi oleh redux

Rizo
sumber
1

Memiliki satu toko di Redux benar-benar yang kita butuhkan dalam banyak kasus, saya menggunakan Redux dan Flux dan percaya Redux melakukan pekerjaan dengan lebih baik!

Jangan lupa toko ada di Objek JavaScript, jadi sementara Anda hanya memiliki satu toko, bagi saya dapat dengan mudah diperpanjang dan digunakan kembali, bagi saya, memiliki satu toko membuatnya lebih mudah untuk dilalui menggunakan alat-alat Redux dev dan tidak tercampur dalam aplikasi besar ...

Konsep satu toko juga meniru database kami, satu sumber kebenaran yang dapat Anda ubah dan Anda dapat mengaksesnya di memori peramban ...

Jika seluruh aplikasi dikelola dengan baik, satu toko dapat cukup untuk mengelola seluruh status aplikasi ...

Alireza
sumber
3
Jadi semua orang harus percaya bahwa satu toko akan melakukan pekerjaan dengan lebih baik dan tidak ada yang bisa menjelaskan mengapa. Itu mengingatkan saya sesuatu ...
puchu