Redux & RxJS, ada persamaannya?


113

Saya tahu Redux adalah "implementasi" Flux yang lebih baik, atau lebih baik mengatakan itu adalah desain ulang untuk menyederhanakan berbagai hal (manajemen status aplikasi).

Saya telah mendengar banyak tentang pemrograman reaktif (RxJS), tetapi saya belum menyelam untuk mempelajarinya.

Jadi pertanyaan saya adalah: apakah ada persimpangan (kesamaan) antara kedua teknologi ini atau keduanya saling melengkapi? ... atau sama sekali berbeda?

Jawaban:


185

Singkatnya, mereka adalah perpustakaan yang sangat berbeda untuk tujuan yang sangat berbeda, tetapi ya ada beberapa kesamaan yang tidak jelas.

Redux adalah alat untuk mengelola status di seluruh aplikasi. Biasanya digunakan sebagai arsitektur untuk UI. Anggap saja sebagai alternatif (setengah dari) Angular.

RxJS adalah pustaka pemrograman reaktif. Biasanya digunakan sebagai alat untuk menyelesaikan tugas asinkron di JavaScript. Anggap saja sebagai alternatif dari Janji.


Pemrograman reaktif adalah paradigma (cara bekerja dan berpikir) dimana perubahan data diamati dari kejauhan . Data tidak berubah dari kejauhan .

Berikut contoh perubahan dari jarak jauh :

// In the controller.js file
model.set('name', 'George');

The Model berubah dari Controller.

Berikut contoh pengamatan dari kejauhan :

// logger.js
store.subscribe(function (data) {
    console.log(data);
});

Di Logger, kami mengamati perubahan data yang terjadi di Store (dari jarak jauh), dan menulis ke konsol.


Redux menggunakan paradigma Reaktif sedikit: Store itu reaktif. Anda tidak mengatur isinya dari kejauhan. Itu sebabnya tidak ada store.set()di Redux. Store mengamati tindakan dari kejauhan, dan mengubah dirinya sendiri. Dan Store memungkinkan orang lain untuk mengamati datanya dari kejauhan.

RxJS juga menggunakan paradigma Reaktif, tetapi alih-alih menjadi arsitektur, RxJS memberi Anda blok bangunan dasar, Observable , untuk mencapai pola "mengamati dari jarak jauh" ini.

Untuk menyimpulkan, hal-hal yang sangat berbeda untuk tujuan yang berbeda, tetapi berbagi beberapa ide.


4
Tidak, Anda tidak boleh menggunakannya bersamaan. Orang-orang telah meniru Redux menggunakan Rx. Google cepat akan menemukan contoh untuk Anda. Jika Anda ingin menggunakan Rx untuk UI reaktif Anda, periksa Cycle.js, kerangka kerja Andre. Saya telah menggunakannya akhir-akhir ini dan itu luar biasa. API telah banyak berubah akhir-akhir ini, tetapi saya yakin dia akhirnya mulai membekukan sebagian darinya.
Joel Dentici

17
menurut redux docs resmi , "Mereka bekerja sama dengan baik."
galki

12
Mereka bekerja sama dengan baik! Ada middleware Redux yang memberi Anda kesempatan untuk menggunakan RxJS dan Observables untuk tindakan Redux. github.com/redux-observable/redux-observable Selain itu saya menulis posting blog tentang How To: robinwieruch.de/redux-observable-rxjs
Robin Wieruch

1
Paradigma Redux membantu membuat basis kode proyek Android saya lebih reaktif. Aliran data kami berasal dari tombol dan bidang lain untuk memperbarui status, dalam hubungannya dengan RxJava, meningkatkan keterbacaan dan kinerja kami. Perpustakaan pasti berjalan dengan baik bersama-sama, dan manfaatnya tidak mengenal bahasa.
Kenny Worden

Mereka bekerja sama dengan baik, tetapi dalam praktiknya Reaktif dapat melakukan untuk Anda apa yang akan dilakukan Redux - sinkronkan status komponen Anda ke model, sehingga sering kali tidak masuk akal untuk menggunakan keduanya
Filip Sobczak

32

Mereka adalah hal yang sangat berbeda.

RxJS dapat digunakan untuk melakukan Pemrograman Reaktif dan merupakan pustaka yang sangat menyeluruh dengan 250+ operator.

Dan Redux seperti yang dijelaskan di repo github "Redux adalah wadah status yang dapat diprediksi untuk aplikasi JavaScript".

Redux hanyalah alat untuk menangani status dalam aplikasi. Namun sebagai perbandingan, Anda dapat membuat aplikasi lengkap hanya dalam RxJS.

Semoga ini membantu :)


3
Jawaban Anda juga bagus @cmdv. Saya tidak melihatnya ketika saya menulis milik saya.
André Staltz

4

Redux hanyalah perpustakaan manajemen negara yang dilengkapi dengan standar yang ditentukan dengan baik untuk operasi pembaruan. Sejauh Anda tetap berpegang pada standar, Anda dapat menjaga aliran data Anda tetap waras dan mudah digunakan. Ini juga membawa kemampuan untuk meningkatkan aliran data dengan middlewares dan penyempurna penyimpanan.

RxJS adalah toolkit untuk pemrograman reaktif. Anda benar-benar dapat menganggap setiap hal yang terjadi di aplikasi Anda sebagai aliran. RxJS memberikan set alat yang sangat kaya untuk mengelola aliran tersebut.

Di mana penyadapan RxJS dan Redux? Dalam redux Anda memperbarui status Anda dengan tindakan dan jelas tindakan ini dapat diperlakukan sebagai aliran. Menggunakan middleware seperti redux-observable (Anda tidak perlu), Anda dapat mengimplementasikan apa yang disebut "logika bisnis" dengan cara yang reaktif. Hal lain adalah Anda dapat membuat observable dari toko redux Anda yang terkadang mungkin lebih mudah daripada menggunakan enhancer.


2

Singkatnya:

Redux: Perpustakaan yang terinspirasi Flux yang digunakan untuk Manajemen Negara .

RxJS: Ini adalah perpustakaan Javascript lain berdasarkan filosofi pemrograman reaktif, digunakan untuk menangani "Streams" (Observables, dll.) [Baca tentang Pemrograman Reaktif untuk memahami konsep Stream].


1

Saya hanya ingin menambahkan beberapa perbedaan pragmatis dari saat saya membuat kode RxJS yang terinspirasi Redux.

Saya memetakan setiap jenis tindakan ke instance Subjek. Setiap komponen berstatus akan memiliki Subjek yang kemudian dipetakan ke dalam fungsi peredam. Semua aliran peredam digabungkan dengan mergedan kemudian scanmengeluarkan status. Nilai default ditetapkan dengan startWithtepat sebelum scan. Saya digunakan publishReplay(1)untuk negara bagian, tetapi mungkin menghapusnya nanti.

Fungsi render murni react hanya akan menjadi tempat di mana Anda menghasilkan data acara dengan mengirimkan semua produser / Subjek.

Jika Anda memiliki komponen anak, Anda perlu menjelaskan bagaimana status tersebut digabungkan menjadi milik Anda. combineLatestmungkin bisa menjadi titik awal yang baik untuk itu.

Perbedaan penting dalam implementasi:

  • Tidak ada middleware, hanya operator rxjs. Saya pikir ini adalah kekuatan dan kelemahan terbesar. Anda masih dapat meminjam konsep, tetapi saya merasa sulit untuk mendapatkan bantuan dari komunitas serupa seperti redux dan cycle.js karena ini adalah solusi khusus lainnya. Itulah mengapa saya perlu menulis "saya" dan bukan "kami" dalam teks ini.

  • Tidak ada sakelar / case atau string untuk jenis tindakan. Anda memiliki cara yang lebih dinamis untuk memisahkan tindakan.

  • rxjs dapat digunakan sebagai alat di tempat lain, dan tidak terkandung dalam manajemen negara.

  • Jumlah produsen lebih sedikit daripada jenis tindakan (?). Saya tidak yakin tentang ini, tetapi Anda dapat memiliki banyak reaksi dalam komponen induk yang mendengarkan komponen anak. Itu berarti kode yang kurang penting, dan lebih sedikit kerumitan.

  • Anda memiliki solusinya. Tidak diperlukan kerangka kerja. Baik dan buruk. Bagaimanapun juga, Anda akan menulis kerangka kerja Anda sendiri.

  • Ini jauh lebih fraktal, dan Anda dapat dengan mudah berlangganan perubahan dari sub-pohon, atau beberapa bagian dari pohon status aplikasi.

    • Tebak betapa mudahnya membuat epik seperti yang dilakukan redux-obseravble? Sangat mudah.

Saya juga mengerjakan manfaat yang jauh lebih besar di mana komponen anak digambarkan sebagai aliran. Ini berarti bahwa kita tidak harus memenuhi status induk dan anak dalam reduksi, karena kita hanya dapat ("hanya") secara rekursif menggabungkan status berdasarkan struktur komponen.

Saya juga berpikir tentang melewatkan react dan menggunakan snabbdom atau yang lainnya sampai React menangani status reaktif dengan lebih baik. Mengapa kita harus membangun negara kita ke atas hanya untuk memecahnya melalui alat peraga lagi? Jadi saya akan mencoba membuat versi 2 dari pola ini dengan Snabbdom.

Berikut cuplikan yang lebih canggih tetapi kecil di mana file state.ts membangun aliran status. Ini adalah status komponen bentuk ajax yang mendapatkan objek bidang (input) dengan aturan validasi dan gaya css. Dalam file ini kami hanya menggunakan nama bidang (kunci objek) untuk menggabungkan semua status anak-anak ke dalam status formulir.

export default function create({
  Observable,
  ajaxInputs
}) {
  const fieldStreams = Object.keys(ajaxInputs)
  .map(function onMap(fieldName) {
    return ajaxInputs[fieldName].state.stream
    .map(function onMap(stateData) {
      return {stateData, fieldName}
    })
  })

  const stateStream = Observable.combineLatest(...fieldStreams)
  .map(function onMap(fieldStreamDataArray) {
    return fieldStreamDataArray.reduce(function onReduce(acc, fieldStreamData) {
    acc[fieldStreamData.fieldName] = fieldStreamData.stateData
    return acc
  }, {})
  })

  return {
    stream: stateStream
  }
}

Meskipun kode mungkin tidak banyak berbicara secara terpisah, kode ini menunjukkan bagaimana Anda dapat membangun status ke atas, dan bagaimana Anda dapat menghasilkan peristiwa dinamis dengan mudah. Harga yang harus dibayar adalah Anda perlu memahami gaya kode yang berbeda. Dan saya suka membayar harga itu.


Setahun kemudian, saya baru menemukan jawaban Anda dan menganggapnya masih valid! Saya melakukan hal serupa dan setuju dengan semua poin Anda. Tetapi pertanyaannya adalah: Apakah Anda masih berpikiran sama hari ini, atau apakah Anda sudah pindah?
Xceno

1
Saya perlu merevisi kritik tentang sakelar / kasus dan jenis tindakan di Redux. Saya masih membuat kode dengan cara yang sama, tetapi mencoba bekerja dengan cara membuatnya bekerja di sisi server. Ketika datang ke kode React, saya telah berhasil melakukan util kecil yang membantu membuat reduksi / updater. Jadi saya masih melakukan hal yang sama, tetapi sedikit lebih halus. Perubahan terbesar adalah saya membiarkan setiap node daun berlangganan aliran di componentDidMount dan berhenti berlangganan di componentDidUnmount. Saya ingin mendapatkan lapisan layanan reaktif juga yang berfungsi di frontend dan backend. Membuat kemajuan di sana.
Marcus Rådell
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.