Menggunakan RxJS dalam React Development untuk Mengelola Status Aplikasi

Penulis materi, terjemahan yang kami terbitkan hari ini, mengatakan bahwa di sini ia ingin menunjukkan proses pengembangan aplikasi Bereaksi sederhana yang menggunakan RxJS. Menurutnya, dia bukan ahli dalam RxJS, karena dia terlibat dalam mempelajari perpustakaan ini dan tidak menolak bantuan orang-orang berpengetahuan. Tujuannya adalah untuk menarik perhatian audiens ke cara-cara alternatif untuk menciptakan aplikasi Bereaksi, untuk menginspirasi pembaca untuk melakukan penelitian independen. Materi ini tidak bisa disebut pengantar RxJS. Salah satu dari banyak cara untuk menggunakan perpustakaan ini dalam pengembangan Bereaksi akan ditampilkan di sini.

gambar

Bagaimana semuanya dimulai


Baru-baru ini, klien saya menginspirasi saya untuk belajar menggunakan RxJS untuk mengelola keadaan aplikasi Bereaksi. Ketika saya mengaudit kode aplikasi untuk klien ini, dia ingin tahu pendapat saya tentang bagaimana dia mengembangkan aplikasi, mengingat sebelumnya itu telah digunakan secara eksklusif negara bagian Bereaksi lokal. Proyek mencapai titik di mana tidak masuk akal untuk hanya mengandalkan React. Pertama, kami berbicara tentang menggunakan Redux atau MobX sebagai cara yang lebih baik untuk mengelola keadaan aplikasi Anda. Klien saya membuat prototipe untuk masing-masing teknologi ini. Tapi dia tidak berhenti pada teknologi ini, membuat prototipe aplikasi Bereaksi yang menggunakan RxJS. Sejak saat itu, percakapan kami menjadi jauh lebih menarik.

Aplikasi yang dimaksud adalah platform perdagangan untuk cryptocurrency. Itu memiliki banyak widget yang datanya diperbarui secara real time. Para pengembang aplikasi ini, antara lain, harus menyelesaikan tugas-tugas sulit berikut:

  • Kelola beberapa permintaan data (tidak sinkron).
  • Pembaruan waktu-nyata dari sejumlah besar widget pada panel kontrol.
  • Solusi untuk masalah widget dan konektivitas data, karena beberapa widget membutuhkan data tidak hanya dari beberapa sumber khusus, tetapi juga dari widget lain.

Akibatnya, kesulitan utama yang dihadapi pengembang tidak terkait dengan perpustakaan Bereaksi itu sendiri, dan selain itu, saya bisa membantu mereka dalam bidang ini. Masalah utama adalah membuat mekanisme internal sistem bekerja dengan benar, mekanisme yang menghubungkan data cryptocurrency dan elemen antarmuka yang dibuat oleh alat React. Di area inilah kemampuan RxJS sangat berguna, dan prototipe yang mereka tunjukkan terlihat sangat menjanjikan.

Menggunakan RxJS di Bereaksi


Misalkan kita memiliki aplikasi yang, setelah melakukan beberapa tindakan lokal, membuat permintaan ke API pihak ketiga . Ini memungkinkan Anda untuk mencari berdasarkan artikel. Sebelum menjalankan permintaan, kita perlu mendapatkan teks yang digunakan untuk membentuk permintaan ini. Secara khusus, kami, menggunakan teks ini, membentuk URL untuk mengakses API. Berikut adalah kode komponen Bereaksi yang mengimplementasikan fungsi ini

import React from 'react'; const App = ({ query, onChangeQuery }) => (  <div>    <h1>React with RxJS</h1>    <input      type="text"      value={query}      onChange={event => onChangeQuery(event.target.value)}    />    <p>{`http://hn.algolia.com/api/v1/search?query=${query}`}</p>  </div> ); export default App; 

Komponen ini tidak memiliki sistem manajemen negara. Status untuk properti query tidak disimpan di mana pun, fungsi onChangeQuery juga tidak memperbarui status. Dalam pendekatan konvensional, komponen seperti itu dilengkapi dengan sistem manajemen negara bagian setempat. Ini terlihat seperti ini:

 class App extends React.Component { constructor(props) {   super(props);   this.state = {     query: '',   }; } onChangeQuery = query => {   this.setState({ query }); }; render() {   return (     <div>       <h1>React with RxJS</h1>       <input         type="text"         value={this.state.query}         onChange={event =>           this.onChangeQuery(event.target.value)         }       />       <p>{`http://hn.algolia.com/api/v1/search?query=${         this.state.query       }`}</p>     </div>   ); } } export default App; 

Namun, ini bukan pendekatan yang akan kita bicarakan di sini. Sebagai gantinya, kami ingin membuat sistem manajemen status aplikasi menggunakan RxJS. Mari kita lihat bagaimana melakukan ini menggunakan Komponen Orde Tinggi (HOC).

Jika Anda mau, Anda dapat menerapkan logika serupa di komponen App Anda, tetapi kemungkinan besar Anda, pada suatu saat dalam pekerjaan Anda pada aplikasi, memutuskan untuk merancang komponen seperti itu dalam bentuk HOC yang cocok untuk digunakan kembali.

Bereaksi dan Komponen Top-Order RxJS


Kami akan mencari cara mengelola keadaan Bereaksi aplikasi menggunakan RxJS, menggunakan komponen orde tinggi untuk tujuan ini. Sebagai gantinya, orang dapat menerapkan templat render props. Akibatnya, jika Anda tidak ingin membuat sendiri komponen tingkat tinggi untuk tujuan ini, Anda dapat menggunakan komponen tingkat tinggi yang dapat diamati. mapPropsStream() dengan mapPropsStream() dan componentFromStream() . Namun dalam panduan ini, kami akan melakukan semuanya sendiri.

 import React from 'react'; const withObservableStream = (...) => Component => { return class extends React.Component {   componentDidMount() {}   componentWillUnmount() {}   render() {     return (       <Component {...this.props} {...this.state} />     );   } }; }; const App = ({ query, onChangeQuery }) => ( <div>   <h1>React with RxJS</h1>   <input     type="text"     value={query}     onChange={event => onChangeQuery(event.target.value)}   />   <p>{`http://hn.algolia.com/api/v1/search?query=${query}`}</p> </div> ); export default withObservableStream(...)(App); 

Sementara komponen orde tinggi RxJS tidak melakukan tindakan apa pun. Ini hanya mentransfer status dan propertinya sendiri ke komponen input, yang rencananya akan diperluas dengan bantuannya. Seperti yang Anda lihat, pada akhirnya, komponen tingkat tinggi akan terlibat dalam mengelola keadaan Bereaksi. Namun, keadaan ini akan diperoleh dari aliran yang diamati. Sebelum kita mulai menerapkan HOC dan menggunakannya dengan komponen App , kita perlu menginstal RxJS:

 npm install rxjs --save 

Sekarang mari kita mulai menggunakan komponen tingkat tinggi dan menerapkan logikanya:

 import React from 'react'; import { BehaviorSubject } from 'rxjs'; ... const App = ({ query, onChangeQuery }) => ( <div>   <h1>React with RxJS</h1>   <input     type="text"     value={query}     onChange={event => onChangeQuery(event.target.value)}   />   <p>{`http://hn.algolia.com/api/v1/search?query=${query}`}</p> </div> ); const query$ = new BehaviorSubject({ query: 'react' }); export default withObservableStream( query$, {   onChangeQuery: value => query$.next({ query: value }), } )(App); 

Komponen App itu sendiri tidak berubah. Kami baru saja menyampaikan dua argumen ke komponen pesanan yang lebih tinggi. Kami menggambarkannya:

  • Objek yang diamati. Argumen query adalah objek yang dapat diamati yang memiliki nilai awal, tetapi, selain itu, mengembalikan, seiring waktu, nilai-nilai baru (karena ini adalah BehaviorSubject ). Siapa pun dapat berlangganan objek yang dapat diamati ini. Inilah yang dikatakan dokumentasi RxJS tentang objek bertipe BehaviorSubject : "Salah satu opsi untuk objek Subject adalah objek BehaviorSubject yang menggunakan konsep" nilai saat ini ". Ia menyimpan nilai terakhir yang diteruskan ke pelanggannya, dan ketika pengamat baru berlangganan, ia segera menerima "nilai saat ini" dari BehaviorSubject . Objek seperti itu sangat cocok untuk menyajikan data, bagian-bagian baru yang muncul seiring waktu. "
  • Sistem untuk mengeluarkan nilai baru untuk objek yang diamati (pemicu). Fungsi onChangeQuery() , melewati HOC ke komponen App , adalah fungsi biasa yang meneruskan nilai berikutnya ke objek yang diamati. Fungsi ini ditransfer dalam objek, karena mungkin diperlukan untuk mentransfer ke komponen urutan tinggi beberapa fungsi yang melakukan tindakan tertentu dengan objek yang diamati.

Setelah membuat objek yang diamati dan berlangganan, aliran untuk permintaan harus bekerja. Namun, hingga sekarang, komponen tingkat tinggi itu sendiri tampak seperti kotak hitam bagi kami. Kami menyadarinya:

 const withObservableStream = (observable, triggers) => Component => { return class extends React.Component {   componentDidMount() {     this.subscription = observable.subscribe(newState =>       this.setState({ ...newState }),     );   }   componentWillUnmount() {     this.subscription.unsubscribe();   }   render() {     return (       <Component {...this.props} {...this.state} {...triggers} />     );   } }; }; 

Komponen tingkat tinggi menerima objek yang dapat diobservasi dan objek dengan pemicu (mungkin objek yang berisi fungsi ini dapat disebut beberapa istilah yang lebih sukses dari leksikon RxJS), diwakili dalam tanda tangan fungsi.

Pemicu hanya melewati HOC ke komponen input. Itulah sebabnya komponen App secara langsung menerima fungsi onChangeQuery() , yang langsung bekerja dengan objek yang diamati, meneruskan nilai baru ke sana.

Objek yang diamati menggunakan componentDidMount() metode siklus hidup untuk masuk dan metode componentDidMount() untuk berhenti berlangganan. Berhenti berlangganan diperlukan untuk mencegah kebocoran memori . Dalam berlangganan objek yang diamati, fungsi hanya mengirim semua data yang masuk dari aliran ke toko negara Bereaksi lokal menggunakan perintah this.setState() .

Mari kita lakukan perubahan kecil pada komponen App , yang akan menghilangkan masalah yang terjadi jika komponen urutan tinggi tidak menetapkan nilai awal untuk properti query . Jika ini tidak dilakukan, maka, di awal pekerjaan, properti query akan berubah menjadi undefined . Berkat perubahan ini, properti ini mendapatkan nilai default.

 const App = ({ query = '', onChangeQuery }) => ( <div>   <h1>React with RxJS</h1>   <input     type="text"     value={query}     onChange={event => onChangeQuery(event.target.value)}   />   <p>{`http://hn.algolia.com/api/v1/search?query=${query}`}</p> </div> ); 

Cara lain untuk mengatasi masalah ini adalah dengan menetapkan keadaan awal untuk query dalam komponen tingkat tinggi:

 const withObservableStream = ( observable, triggers, initialState, ) => Component => { return class extends React.Component {   constructor(props) {     super(props);     this.state = {       ...initialState,     };   }   componentDidMount() {     this.subscription = observable.subscribe(newState =>       this.setState({ ...newState }),     );   }   componentWillUnmount() {     this.subscription.unsubscribe();   }   render() {     return (       <Component {...this.props} {...this.state} {...triggers} />     );   } }; }; const App = ({ query, onChangeQuery }) => ( ... ); export default withObservableStream( query$, {   onChangeQuery: value => query$.next({ query: value }), }, {   query: '', } )(App); 

Jika Anda mencoba aplikasi ini sekarang, kotak input harus berfungsi seperti yang diharapkan. Komponen App menerima dari HOC, dalam bentuk properti, hanya status query dan fungsi onChangeQuery untuk mengubah status.

Mengambil dan mengubah keadaan terjadi melalui objek yang dapat diamati RxJS, meskipun fakta bahwa toko keadaan Bereaksi internal digunakan di dalam komponen tingkat tinggi. Saya tidak dapat menemukan solusi yang jelas untuk masalah streaming data dari berlangganan objek yang diamati langsung ke properti komponen yang diperluas ( App ). Itu sebabnya saya harus menggunakan keadaan lokal Bereaksi dalam bentuk lapisan menengah, yang, selain itu, nyaman dalam hal apa yang menyebabkan rendering ulang. Jika Anda tahu cara lain untuk mencapai tujuan yang sama - Anda dapat membagikannya di komentar.

Menggabungkan Objek yang Diamati dalam Bereaksi


Mari kita buat aliran nilai kedua, yang, seperti properti query , dapat digunakan dalam komponen App . Nanti kita akan menggunakan kedua nilai tersebut, bekerja dengannya menggunakan objek lain yang bisa diamati.

 const SUBJECT = { POPULARITY: 'search', DATE: 'search_by_date', }; const App = ({ query = '', subject, onChangeQuery, onSelectSubject, }) => ( <div>   <h1>React with RxJS</h1>   <input     type="text"     value={query}     onChange={event => onChangeQuery(event.target.value)}   />   <div>     {Object.values(SUBJECT).map(value => (       <button         key={value}         onClick={() => onSelectSubject(value)}         type="button"       >         {value}       </button>     ))}   </div>   <p>{`http://hn.algolia.com/api/v1/${subject}?query=${query}`}</p> </div> ); 

Seperti yang Anda lihat, parameter subject dapat digunakan untuk menyaring permintaan saat membuat URL yang digunakan untuk mengakses API. Yaitu, materi dapat dicari berdasarkan popularitasnya atau pada tanggal publikasi. Selanjutnya, buat objek lain yang bisa diamati yang dapat digunakan untuk mengubah parameter subject . Dapat diamati ini dapat digunakan untuk mengaitkan komponen App dengan komponen urutan yang lebih tinggi. Jika tidak, properti yang diteruskan ke komponen App tidak akan berfungsi.

 import React from 'react'; import { BehaviorSubject, combineLatest } from 'rxjs/index'; ... const query$ = new BehaviorSubject({ query: 'react' }); const subject$ = new BehaviorSubject(SUBJECT.POPULARITY); export default withObservableStream( combineLatest(subject$, query$, (subject, query) => ({   subject,   query, })), {   onChangeQuery: value => query$.next({ query: value }),   onSelectSubject: subject => subject$.next(subject), }, )(App); 

Pemicu onSelectSubject() bukanlah hal baru. Melalui tombol, dapat digunakan untuk beralih di antara dua status subject . Tetapi objek yang diamati dipindahkan ke komponen tingkat tinggi adalah sesuatu yang baru. Ini menggunakan fungsi combineLatest() dari RxJS untuk menggabungkan nilai-nilai yang dikembalikan terakhir dari dua (atau lebih) stream yang diamati. Setelah berlangganan objek yang diamati, jika salah satu nilai ( query atau subject ) diubah, pelanggan akan menerima kedua nilai tersebut.

Sebuah pelengkap mekanisme yang diimplementasikan oleh fungsi combineLatest() adalah argumen terakhirnya. Di sini Anda dapat mengatur urutan pengembalian nilai yang dihasilkan oleh objek yang diamati. Dalam kasus kami, kami membutuhkan mereka untuk diwakili sebagai objek. Ini akan memungkinkan, seperti sebelumnya, menghancurkannya dalam komponen tingkat tinggi dan menuliskannya ke status Bereaksi lokal. Karena kita sudah memiliki struktur yang diperlukan, kita dapat menghilangkan langkah membungkus objek dari objek query diamati.

 ... const query$ = new BehaviorSubject('react'); const subject$ = new BehaviorSubject(SUBJECT.POPULARITY); export default withObservableStream( combineLatest(subject$, query$, (subject, query) => ({   subject,   query, })), {   onChangeQuery: value => query$.next(value),   onSelectSubject: subject => subject$.next(subject), }, )(App); 

Objek sumber, { query: '', subject: 'search' } , serta semua objek lain yang dikembalikan oleh aliran gabungan dari objek yang diamati, cocok untuk merusaknya dalam komponen tingkat tinggi dan untuk menulis nilai yang sesuai ke keadaan Bereaksi lokal. Setelah memperbarui keadaan, seperti sebelumnya, rendering dilakukan. Ketika Anda meluncurkan aplikasi yang diperbarui, Anda harus dapat mengubah kedua nilai menggunakan bidang input dan tombol. Nilai yang diubah memengaruhi URL yang digunakan untuk mengakses API. Sekalipun hanya satu dari nilai-nilai ini yang berubah, nilai yang lain mempertahankan status terakhirnya, karena fungsi combineLatest() selalu menggabungkan nilai terbaru yang dikeluarkan dari aliran yang diamati.

Aksioma dan RxJS dalam Bereaksi


Sekarang di sistem kami, URL untuk mengakses API dibangun berdasarkan dua nilai dari objek yang dapat diamati yang dikombinasikan, yang mencakup dua objek yang dapat diamati lainnya. Di bagian ini, kami akan menggunakan URL untuk memuat data dari API. Anda mungkin dapat menggunakan sistem React loading data , tetapi ketika menggunakan objek yang dapat diamati RxJS, Anda perlu menambahkan aliran lain yang dapat diamati ke aplikasi kami.

Sebelum kita mulai bekerja pada objek yang diamati berikutnya, instal aksioma . Ini adalah perpustakaan yang akan kita gunakan untuk memuat data dari stream ke dalam program.

 npm install axios --save 

Sekarang bayangkan bahwa kita memiliki berbagai artikel yang harus dihasilkan oleh komponen App . Di sini, sebagai nilai parameter default yang sesuai, kami menggunakan array kosong, melakukan hal yang sama seperti yang kami lakukan dengan parameter lainnya.

 ... const App = ({ query = '', subject, stories = [], onChangeQuery, onSelectSubject, }) => ( <div>   ...   <p>{`http://hn.algolia.com/api/v1/${subject}?query=${query}`}</p>   <ul>     {stories.map(story => (       <li key={story.objectID}>         <a href={story.url || story.story_url}>           {story.title || story.story_title}         </a>       </li>     ))}   </ul> </div> ); 

Untuk setiap artikel dalam daftar, nilai mundur digunakan karena fakta bahwa API yang kami akses tidak seragam. Sekarang - yang paling menarik - implementasi objek baru yang dapat diamati yang bertanggung jawab untuk memuat data ke dalam aplikasi Bereaksi yang akan memvisualisasikannya.

 import React from 'react'; import axios from 'axios'; import { BehaviorSubject, combineLatest } from 'rxjs'; import { flatMap, map } from 'rxjs/operators'; ... const query$ = new BehaviorSubject('react'); const subject$ = new BehaviorSubject(SUBJECT.POPULARITY); const fetch$ = combineLatest(subject$, query$).pipe( flatMap(([subject, query]) =>   axios(`http://hn.algolia.com/api/v1/${subject}?query=${query}`), ), map(result => result.data.hits), ); ... 

Objek baru yang dapat diamati adalah, sekali lagi, kombinasi dari subject dan query dapat diamati, karena, untuk membangun URL yang dengannya kita akan mengakses API untuk memuat data, kita membutuhkan kedua nilai tersebut. Dalam metode pipe() dari objek yang diamati, kita dapat menggunakan apa yang disebut "operator RxJS" untuk melakukan tindakan tertentu dengan nilai-nilai. Dalam kasus ini, kami memetakan dua nilai yang ditempatkan dalam kueri, yang digunakan aksioma untuk mendapatkan hasilnya. Di sini kita menggunakan operator flatMap() dan bukan map() untuk mengakses hasil dari janji yang berhasil diselesaikan, dan bukan ke janji yang dikembalikan itu sendiri. Akibatnya, setelah berlangganan objek baru yang dapat diamati ini, setiap kali subject baru atau nilai query dimasukkan ke dalam sistem dari objek lain yang dapat diamati, query baru dijalankan, dan hasilnya berada dalam fungsi berlangganan.

Sekarang, sekali lagi, kami dapat memberikan komponen baru yang dapat diamati ke komponen tingkat tinggi. Kami memiliki argumen terakhir untuk fungsi combineLatest() kami miliki, ini memungkinkan untuk memetakannya langsung ke properti yang disebut stories . Pada akhirnya, ini menunjukkan bagaimana data ini sudah digunakan dalam komponen App .

 export default withObservableStream( combineLatest(   subject$,   query$,   fetch$,   (subject, query, stories) => ({     subject,     query,     stories,   }), ), {   onChangeQuery: value => query$.next(value),   onSelectSubject: subject => subject$.next(subject), }, )(App); 

Tidak ada pemicu di sini, karena objek yang diamati diaktifkan secara tidak langsung oleh dua aliran yang diamati lainnya. Setiap kali nilai dalam bidang input ( query ) diubah atau tombol ( subject ) diklik, ini memengaruhi objek fetch diamati, yang berisi nilai terbaru dari kedua aliran.

Namun, mungkin kita tidak perlu bahwa setiap kali kita mengubah nilai di bidang input, ini akan memengaruhi objek fetch diamati. Selain itu, kami tidak ingin fetch terpengaruh jika nilainya adalah string kosong. Itulah sebabnya kami dapat memperluas objek query dapat diamati menggunakan pernyataan debounce , yang menghilangkan terlalu sering perubahan kueri. Yaitu, berkat mekanisme ini, acara baru diterima hanya setelah waktu yang telah ditentukan setelah acara sebelumnya. Selain itu, kami menggunakan operator filter sini, yang memfilter peristiwa aliran jika string query kosong.

 import React from 'react'; import axios from 'axios'; import { BehaviorSubject, combineLatest, timer } from 'rxjs'; import { flatMap, map, debounce, filter } from 'rxjs/operators'; ... const queryForFetch$ = query$.pipe( debounce(() => timer(1000)), filter(query => query !== ''), ); const fetch$ = combineLatest(subject$, queryForFetch$).pipe( flatMap(([subject, query]) =>   axios(`http://hn.algolia.com/api/v1/${subject}?query=${query}`), ), map(result => result.data.hits), ); ... 

Pernyataan debounce melakukan pekerjaan memasukkan data ke dalam bidang. Namun, ketika sebuah tombol mengklik pada nilai subject , permintaan tersebut harus segera dieksekusi.

Sekarang, nilai awal untuk query dan subject , yang kita lihat ketika komponen App ditampilkan untuk pertama kalinya, tidak sama dengan yang diperoleh dari nilai awal objek yang diamati:

 const query$ = new BehaviorSubject('react'); const subject$ = new BehaviorSubject(SUBJECT.POPULARITY); 

subject ditulis dalam subject , string kosong dalam query . Ini disebabkan oleh fakta bahwa nilai-nilai inilah yang kami berikan sebagai parameter default untuk merestrukturisasi fungsi komponen App dalam tanda tangan. Alasan untuk ini adalah karena kita perlu menunggu permintaan awal dieksekusi oleh objek fetch dapat diamati. Karena saya tidak tahu persis bagaimana cara segera mendapatkan nilai dari query dapat diamati dan objek subject dalam komponen tingkat tinggi untuk menulisnya ke keadaan lokal, saya memutuskan untuk mengatur keadaan awal untuk komponen tingkat tinggi lagi.

 const withObservableStream = ( observable, triggers, initialState, ) => Component => { return class extends React.Component {   constructor(props) {     super(props);     this.state = {       ...initialState,     };   }   componentDidMount() {     this.subscription = observable.subscribe(newState =>       this.setState({ ...newState }),     );   }   componentWillUnmount() {     this.subscription.unsubscribe();   }   render() {     return (       <Component {...this.props} {...this.state} {...triggers} />     );   } }; }; 

Sekarang keadaan awal dapat diberikan ke komponen tingkat tinggi sebagai argumen ketiga. Di masa mendatang, kita dapat menghapus pengaturan default untuk komponen App .

 ... const App = ({ query, subject, stories, onChangeQuery, onSelectSubject, }) => ( ... ); export default withObservableStream( combineLatest(   subject$,   query$,   fetch$,   (subject, query, stories) => ({     subject,     query,     stories,   }), ), {   onSelectSubject: subject => subject$.next(subject),   onChangeQuery: value => query$.next(value), }, {   query: 'react',   subject: SUBJECT.POPULARITY,   stories: [], }, )(App); 

Yang membuat saya khawatir saat ini adalah bahwa keadaan awal juga diatur dalam deklarasi objek yang diamati, query$ dan subject$ . Pendekatan ini rawan kesalahan, karena inisialisasi objek yang diamati dan keadaan awal komponen tingkat tinggi memiliki nilai yang sama. Saya akan lebih menyukainya jika, sebaliknya, nilai-nilai awal diekstraksi dari objek yang diamati dalam komponen tingkat tinggi untuk mengatur keadaan awal. Mungkin salah satu pembaca materi ini akan dapat berbagi saran dalam komentar tentang cara melakukan ini.

Kode untuk proyek perangkat lunak yang kami lakukan di sini dapat ditemukan di sini .

Ringkasan


Tujuan utama artikel ini adalah untuk menunjukkan pendekatan alternatif untuk mengembangkan aplikasi Bereaksi menggunakan RxJS. Kami harap dia memberi Anda makanan untuk dipikirkan. Terkadang Redux dan MobX tidak diperlukan, tetapi mungkin dalam situasi seperti itu, RxJS akan sesuai dengan proyek tertentu.

Pembaca yang budiman! Apakah Anda menggunakan RxJS ketika mengembangkan Bereaksi aplikasi?

Source: https://habr.com/ru/post/id428081/


All Articles