Dalam aplikasi Flux hanya ada satu Dispatcher. Semua data mengalir melalui hub pusat ini. Memiliki Dispatcher tunggal memungkinkannya untuk mengelola semua Toko. Ini menjadi penting ketika Anda membutuhkan pembaruan Store # 1 sendiri, dan kemudian perbarui Store # 2 itu sendiri berdasarkan Aksi dan pada kondisi Store # 1. Flux mengasumsikan situasi ini adalah kemungkinan dalam aplikasi besar. Idealnya situasi ini tidak perlu terjadi, dan pengembang harus berusaha untuk menghindari kompleksitas ini, jika memungkinkan. Tapi Dispatcher singleton siap menanganinya ketika saatnya tiba.
Toko juga lajang. Mereka harus tetap independen dan terpisah sebanyak mungkin - alam semesta mandiri yang bisa di-query dari Controller-View. Satu-satunya jalan menuju Store adalah melalui panggilan balik yang terdaftar pada Dispatcher. Satu-satunya jalan keluar adalah melalui fungsi pengambil. Toko juga menerbitkan acara ketika keadaannya telah berubah, sehingga Pengendali-Tampilan dapat mengetahui kapan harus mengajukan permintaan untuk keadaan baru, menggunakan getter.
Di contoh aplikasi Anda, akan ada satu PostStore
. Toko yang sama ini dapat mengelola posting di "halaman" (halaman semu) yang lebih mirip dengan Umpan Berita FB, tempat posting muncul dari pengguna yang berbeda. Domain logisnya adalah daftar posting, dan dapat menangani semua daftar posting. Ketika kami pindah dari halaman semu ke halaman semu, kami ingin menginisialisasi ulang keadaan toko untuk mencerminkan keadaan baru. Kami mungkin juga ingin men-cache keadaan sebelumnya di localStorage sebagai optimisasi untuk bergerak bolak-balik antara halaman semu, tetapi kecenderungan saya adalah untuk mengatur PageStore
yang menunggu semua toko lain, mengelola hubungan dengan localStorage untuk semua toko di halaman semu, dan kemudian memperbarui kondisinya sendiri. Perhatikan bahwa ini tidak PageStore
akan menyimpan apa pun tentang pos - itulah domain dariPostStore
. Itu hanya akan tahu apakah halaman pseudo tertentu telah di-cache atau tidak, karena halaman pseudo adalah domainnya.
The PostStore
akan memiliki initialize()
metode. Metode ini akan selalu menghapus status lama, bahkan jika ini adalah inisialisasi pertama, dan kemudian membuat status berdasarkan data yang diterima melalui Aksi, melalui Dispatcher. Pindah dari satu halaman semu ke halaman lain mungkin akan melibatkan PAGE_UPDATE
tindakan, yang akan memicu permohonan initialize()
. Ada detail untuk dikerjakan di sekitar pengambilan data dari cache lokal, pengambilan data dari server, rendering optimistis dan status kesalahan XHR, tapi ini adalah ide umum.
Jika halaman pseudo tertentu tidak memerlukan semua Toko dalam aplikasi, saya tidak sepenuhnya yakin ada alasan untuk menghancurkan yang tidak digunakan, selain kendala memori. Tetapi toko biasanya tidak menggunakan banyak memori. Anda hanya perlu memastikan untuk menghapus acara pendengar di Controller-Views yang Anda hancurkan. Ini dilakukan dalam componentWillUnmount()
metode Bereaksi .
UserListStore
, dengan semua pengguna yang relevan di dalamnya. Dan setiap pengguna akan memiliki beberapa bendera boolean yang menggambarkan hubungan dengan profil pengguna saat ini. Sesuatu seperti{ follower: true, followed: false }
, misalnya. MetodegetFolloweds()
dangetFollowers()
akan mengambil set pengguna yang berbeda yang Anda butuhkan untuk UI.(Catatan: Saya telah menggunakan sintaks ES6 menggunakan opsi JSX Harmony.)
Sebagai latihan, saya menulis contoh aplikasi Flux yang memungkinkan untuk menjelajah
Github users
dan repo.Ini didasarkan pada jawaban fisherwebdev tetapi juga mencerminkan pendekatan yang saya gunakan untuk menormalkan respons API.
Saya berhasil mendokumentasikan beberapa pendekatan yang telah saya coba saat mempelajari Flux.
Saya mencoba untuk tetap dekat dengan dunia nyata (pagination, tidak ada API localStorage palsu).
Ada beberapa bit di sini saya sangat tertarik pada:
switch
dengan aksi ;Bagaimana Saya Mengklasifikasikan Toko
Saya mencoba menghindari beberapa duplikasi yang saya lihat di contoh Flux lain, khususnya di Toko. Saya merasa berguna untuk membagi Toko secara logis ke dalam tiga kategori:
Toko Konten menampung semua entitas aplikasi. Segala sesuatu yang memiliki ID membutuhkan Content Store-nya sendiri. Komponen yang membuat item individual meminta Content Store untuk data baru.
Konten Toko memanen objek mereka dari semua tindakan server. Misalnya,
UserStore
perhatikanaction.response.entities.users
apakah ada tindakan apa pun yang diluncurkan. Tidak perlu untukswitch
. Normalizr memudahkan untuk meratakan setiap respons API ke format ini.Daftar Toko melacak ID entitas yang muncul di beberapa daftar global (misalnya "umpan", "pemberitahuan Anda"). Dalam proyek ini, saya tidak memiliki Toko seperti itu, tetapi saya pikir saya akan tetap menyebutkannya. Mereka menangani pagination.
Mereka biasanya menanggapi hanya beberapa tindakan (misalnya
REQUEST_FEED
,REQUEST_FEED_SUCCESS
,REQUEST_FEED_ERROR
).Daftar Toko Terindeks seperti Daftar Toko tetapi mereka mendefinisikan hubungan satu-ke-banyak. Misalnya, "pelanggan pengguna", "stargazer repositori", "repositori pengguna". Mereka juga menangani pagination.
Mereka juga biasanya menanggapi hanya beberapa tindakan (misalnya
REQUEST_USER_REPOS
,REQUEST_USER_REPOS_SUCCESS
,REQUEST_USER_REPOS_ERROR
).Di sebagian besar aplikasi sosial, Anda akan memiliki banyak ini dan Anda ingin dapat membuatnya dengan cepat.
Catatan: ini bukan kelas aktual atau sesuatu; itu hanya bagaimana saya suka berpikir tentang Toko. Saya membuat beberapa pembantu.
StoreUtils
createStore
Metode ini memberi Anda Toko paling dasar:
Saya menggunakannya untuk membuat semua Toko.
isInBag
,mergeIntoBag
Pembantu kecil berguna untuk Toko Konten.
PaginatedList
Menyimpan status pagination dan memberlakukan pernyataan tertentu (tidak dapat mengambil halaman saat mengambil, dll).
PaginatedStoreUtils
createListStore
,createIndexedListStore
,createListActionHandler
Jadikan pembuatan Toko Daftar Terindeks sesederhana mungkin dengan menyediakan metode boilerplate dan penanganan tindakan:
createStoreMixin
Mixin yang memungkinkan komponen untuk mendengarkan Toko yang mereka minati, misalnya
mixins: [createStoreMixin(UserStore)]
.sumber
Jadi dalam Reflux konsep Dispatcher dihapus dan Anda hanya perlu berpikir dalam hal aliran data melalui tindakan dan toko. Yaitu
Setiap panah di sini memodelkan bagaimana aliran data didengarkan, yang pada gilirannya berarti bahwa data mengalir dalam arah yang berlawanan. Angka aktual untuk aliran data adalah ini:
Dalam kasus penggunaan Anda, jika saya mengerti dengan benar, kami memerlukan
openUserProfile
tindakan yang memulai pemuatan profil pengguna dan mengalihkan halaman dan juga beberapa tindakan pemuatan posting yang akan memuat posting ketika halaman profil pengguna dibuka dan selama acara gulir yang tak terbatas. Jadi saya bayangkan kita memiliki penyimpanan data berikut dalam aplikasi:Di Reflux Anda akan mengaturnya seperti ini:
Tindakannya
Toko halaman
Toko profil pengguna
Toko posting
Komponen-komponennya
Saya berasumsi Anda memiliki komponen untuk seluruh tampilan halaman, halaman profil pengguna dan daftar posting. Yang berikut perlu disambungkan:
Action.openUserProfile
dengan id yang benar selama acara klik itu.currentPageStore
sehingga ia tahu halaman yang akan dituju.currentUserProfileStore
sehingga ia tahu apa yang ditampilkan data profil penggunacurrentPostsStore
untuk menerima posting yang dimuatAction.loadMorePosts
.Dan itu sudah cukup.
sumber