Arsitektur redux. Ya atau tidak

Penulis materi, terjemahan yang kami terbitkan hari ini, mengatakan bahwa ia adalah bagian dari tim messenger Hike , yang terlibat dalam fitur baru aplikasi. Tujuan dari tim ini adalah untuk menerjemahkan menjadi kenyataan dan mengeksplorasi ide-ide yang mungkin disukai pengguna. Ini berarti bahwa pengembang perlu bertindak cepat, dan bahwa mereka sering harus membuat perubahan pada inovasi yang mereka teliti, yang ditujukan untuk membuat pekerjaan pengguna senyaman dan senyaman mungkin. Mereka lebih suka melakukan eksperimen menggunakan React Native, karena perpustakaan ini mempercepat pengembangan dan memungkinkan Anda untuk menggunakan kode yang sama pada platform yang berbeda. Selain itu, mereka menggunakan pustaka Redux.



Ketika pengembang dari Hike mulai mengerjakan sesuatu yang baru, maka, ketika membahas arsitektur solusi yang diselidiki, mereka memiliki beberapa pertanyaan:

  • Ini adalah kesempatan eksperimental yang dapat, seperti yang mereka katakan, "tidak terbang", dan itu harus ditinggalkan. Mengingat hal ini, apakah perlu menghabiskan waktu merancang arsitektur aplikasi?
  • Aplikasi eksperimental hanyalah sebuah MVP, produk minimal yang layak yang memiliki 1-2 layar dan perlu dibuat secepat mungkin. Mengingat ini, haruskah saya menghubungi Redux?
  • Bagaimana Anda membenarkan waktu yang dibutuhkan manajer produk untuk menyiapkan infrastruktur pendukung untuk aplikasi eksperimental?

Faktanya, Redux membantu Anda menemukan jawaban yang tepat untuk semua pertanyaan ini. Arsitektur redux membantu memisahkan status aplikasi dari React. Ini memungkinkan Anda untuk membuat repositori global yang terletak di tingkat atas aplikasi dan menyediakan akses status untuk semua komponen lainnya.

Pemisahan tanggung jawab


Apa itu "pemisahan tanggung jawab"? Inilah yang dikatakan Wikipedia tentang itu: β€œDalam ilmu komputer, pembagian tanggung jawab adalah proses membagi program komputer menjadi blok fungsional yang tumpang tindih fungsi satu sama lain sesedikit mungkin. Dalam kasus yang lebih umum, pembagian tanggung jawab adalah penyederhanaan dari satu proses untuk memecahkan masalah dengan membaginya menjadi proses interaksi untuk menyelesaikan subtugas. "

Arsitektur Redux memungkinkan Anda untuk menerapkan prinsip pemisahan tanggung jawab dalam aplikasi, memecahnya menjadi empat blok, ditunjukkan pada gambar berikut.


Arsitektur Redux

Berikut ini deskripsi singkat dari blok-blok ini:

  • Representasi atau komponen antarmuka pengguna (Komponen UI) menyerupai fungsi murni (yaitu, fungsi-fungsi yang tidak mengubah data yang ditransfer ke mereka dan memiliki beberapa properti lainnya) yang bertanggung jawab untuk menampilkan informasi pada layar berdasarkan data yang ditransfer dari toko. Mereka tidak mengubah data secara langsung. Ketika suatu peristiwa terjadi, atau jika pengguna berinteraksi dengan mereka, mereka beralih ke pencipta tindakan.
  • Pencipta Tindakan bertanggung jawab untuk membuat dan mengirim tindakan.
  • Pengecil menerima tindakan yang dijadwalkan dan memperbarui status repositori.
  • Data Store bertanggung jawab untuk menyimpan data aplikasi.

Pertimbangkan arsitektur Redux sebagai contoh.

Bagaimana jika komponen yang berbeda memerlukan data yang sama?


Aplikasi Hike memiliki layar yang menampilkan daftar teman pengguna. Informasi tentang jumlah mereka ditampilkan di bagian atas layar ini.


Layar teman di aplikasi Hike

Ada 3 komponen Bereaksi di sini:

  • FriendRow adalah komponen yang berisi nama teman pengguna dan beberapa informasi lain tentang dia.
  • FriendsHeader - komponen yang menampilkan tulisan "TEMAN SAYA" dan informasi tentang jumlah teman.
  • ContainerView adalah komponen wadah yang menggabungkan judul layar yang diwakili oleh komponen FriendsHeader dan daftar teman yang diperoleh dengan melintasi larik yang berisi informasi tentang teman-teman pengguna, yang masing-masing elemen ditampilkan di layar oleh komponen FriendRow .

Berikut adalah kode untuk friendsContainer.js untuk menggambarkan hal di atas:

 class Container extends React.Component {   constructor(props) {     super(props);     this.state = {       friends: []     };   }   componentDidMount() {     FriendsService.fetchFriends().then((data) => {       this.setState({         friends: data       });     });   }   render() {     const { friends } = this.state;     return (       <View style={styles.flex}>       <FriendsHeader count={friends.length} text='My friends' />       {friends.map((friend) => (<FriendRow {...friend} />)) }       </View>     );   } } 

Cara yang sangat jelas untuk membuat halaman aplikasi seperti itu adalah memuat data tentang teman ke dalam komponen wadah dan meneruskannya sebagai properti ke komponen anak.

Mari kita pikirkan fakta bahwa data tentang teman ini mungkin diperlukan dalam beberapa komponen lain yang digunakan dalam aplikasi.


Mendaki layar chat

Misalkan aplikasi memiliki layar obrolan, yang juga berisi daftar teman. Dapat dilihat bahwa data yang sama digunakan pada layar dengan daftar teman dan pada layar obrolan. Apa yang harus dilakukan dalam situasi yang sama? Kami memiliki dua opsi:

  • Anda dapat mengunduh lagi data teman Anda di komponen ComposeChat bertanggung jawab untuk menampilkan daftar obrolan. Namun, pendekatan ini tidak terlalu baik, karena penggunaannya akan berarti duplikasi data dan dapat menyebabkan masalah dengan sinkronisasi.
  • Anda dapat mengunduh data tentang teman di komponen tingkat atas (wadah utama aplikasi) dan mentransfer data ini ke komponen yang bertanggung jawab untuk menampilkan daftar teman dan menampilkan daftar obrolan. Selain itu, kita perlu meneruskan fungsi ke komponen ini untuk memperbarui data teman, yang diperlukan untuk mendukung sinkronisasi data antara komponen. Pendekatan ini akan mengarah pada fakta bahwa komponen tingkat atas akan secara harfiah dikemas dengan metode dan data yang tidak secara langsung digunakan.

Kedua opsi ini tidak begitu menarik. Sekarang mari kita lihat bagaimana masalah kita dapat dipecahkan dengan menggunakan arsitektur Redux.

Menggunakan Redux


Di sini kita berbicara tentang mengatur pekerjaan dengan data menggunakan penyimpanan, pembuat tindakan, reduksi, dan dua komponen antarmuka pengguna.

▍1. Gudang data


Repositori berisi data yang diunggah tentang teman-teman pengguna. Data ini dapat dikirim ke komponen apa saja jika diperlukan di sana.

▍2. Pembuat aksi


Dalam hal ini, pencipta tindakan digunakan untuk mengirimkan acara yang bertujuan untuk menyimpan dan memperbarui data tentang teman. Berikut adalah kode untuk friendsActions.js :

 export const onFriendsFetch = (friendsData) => { return {   type: 'FRIENDS_FETCHED',   payload: friendsData }; }; 

▍3. Reduksi


Pengurangan menunggu acara yang mewakili tindakan yang dijadwalkan tiba dan memperbarui teman-teman mereka. Berikut adalah kode untuk friendsReducer.js :

 const INITIAL_STATE = {      friends: [],   friendsFetched: false }; function(state = INITIAL_STATE, action) {   switch(action.type) {   case 'FRIENDS_FETCHED':       return {           ...state,           friends: action.payload,           friendsFetched: true       };   } } 

▍4. Komponen Cantuman Teman


Komponen wadah ini menampilkan data teman dan memperbarui antarmuka saat mereka berubah. Selain itu, dia bertanggung jawab untuk mengunduh data dari repositori jika dia tidak memilikinya. Berikut adalah kode untuk friendsContainer.js :

 class Container extends React.Component {   constructor(props) {     super(props);   }   componentDidMount() {     if(!this.props.friendsFetched) {       FriendsService.fetchFriends().then((data) => {         this.props.onFriendsFetch(data);       });     }   }   render() {     const { friends } = this.props;     return (       <View style={styles.flex}>       <FriendsHeader count={friends.length} text='My friends' />       {friends.map((friend) => (<FriendRow {...friend} />)) }       </View>     );   } } const mapStateToProps = (state) => ({ ...state.friendsReducer }); const mapActionToProps = (dispatch) => ({ onFriendsFetch: (data) => {   dispatch(FriendActions.onFriendsFetch(data)); } }); export default connect(mapStateToProps, mapActionToProps)(Container); 

▍5. Komponen Daftar Obrolan


Komponen wadah ini juga menggunakan data dari penyimpanan dan menanggapi pembaruannya.

Tentang Implementasi Arsitektur Redux


Mungkin diperlukan satu atau dua hari untuk membawa arsitektur yang dijelaskan di atas ke kondisi kerja, tetapi ketika perubahan perlu dilakukan untuk proyek, mereka dibuat sangat sederhana dan cepat. Jika Anda perlu menambahkan komponen baru ke aplikasi yang menggunakan data tentang teman, Anda dapat melakukan ini tanpa harus khawatir tentang sinkronisasi data atau bahwa Anda harus mengulang komponen lain. Hal yang sama berlaku untuk menghapus komponen.

Pengujian


Saat menggunakan Redux, setiap blok aplikasi dapat diuji secara independen.
Misalnya, setiap komponen antarmuka pengguna dapat dengan mudah dikenakan pengujian unit, karena ini adalah data yang independen. Intinya adalah bahwa fungsi yang mewakili komponen seperti itu selalu mengembalikan representasi yang sama untuk data yang sama. Ini membuat aplikasi dapat diprediksi dan mengurangi kemungkinan kesalahan yang terjadi selama visualisasi data.

Setiap komponen dapat diuji secara komprehensif menggunakan berbagai data. Pengujian semacam itu mengungkapkan masalah tersembunyi dan membantu memastikan kode berkualitas tinggi.

Perlu dicatat bahwa tidak hanya komponen yang bertanggung jawab untuk visualisasi data, tetapi juga reduksi dan pembuat tindakan dapat dikenakan pengujian independen.

Redux memang hebat, tetapi menggunakan teknologi ini kami mengalami beberapa kesulitan.

Kesulitan Menggunakan Redux


▍ Kelebihan kode templat


Untuk mengimplementasikan arsitektur Redux dalam suatu aplikasi, Anda harus menghabiskan banyak waktu, sambil menghadapi segala macam konsep dan entitas aneh.

Ini adalah apa yang disebut kereta luncur (thunks), reduksi (reduksi), aksi (aksi), lapisan middleware (middlewares), ini adalah fungsi mapStateToProps dan mapDispatchToProps , serta banyak lagi. Diperlukan waktu untuk mempelajari semua ini, dan untuk mempelajari cara menggunakannya dengan benar, diperlukan latihan. Ada banyak file dalam proyek ini, dan, misalnya, satu perubahan kecil dalam komponen untuk visualisasi data mungkin membuatnya perlu untuk membuat perubahan pada empat file.

Red Redux vault adalah singleton


Di Redux, gudang data dibangun menggunakan pola singleton, meskipun komponen dapat memiliki banyak instance. Paling sering ini bukan masalah, tetapi dalam situasi tertentu, pendekatan seperti itu untuk penyimpanan data dapat membuat beberapa kesulitan. Misalnya, bayangkan ada dua contoh komponen. Ketika data berubah dalam salah satu contoh ini, perubahan itu memengaruhi contoh lain. Dalam kasus-kasus tertentu, perilaku ini mungkin tidak diinginkan, mungkin perlu untuk setiap instance komponen untuk menggunakan salinan data sendiri.

Ringkasan


Ingat pertanyaan utama kami, yaitu apakah sepadan dengan waktu dan upaya untuk mengimplementasikan arsitektur Redux. Kami, dalam menanggapi pertanyaan ini, mengatakan Redux "ya." Arsitektur ini membantu menghemat waktu dan upaya dalam mengembangkan dan mengembangkan aplikasi. Menggunakan Redux memudahkan programmer untuk sering melakukan perubahan pada aplikasi, dan membuat pengujian lebih mudah. Tentu saja, arsitektur Redux menyediakan sejumlah kode boilerplate, tetapi membantu memecah kode menjadi modul yang nyaman digunakan. Setiap modul tersebut dapat diuji secara terpisah dari modul lainnya, yang membantu mengidentifikasi kesalahan pada tahap pengembangan dan memungkinkan untuk memastikan program berkualitas tinggi.

Pembaca yang budiman! Apakah Anda menggunakan Redux dalam proyek Anda?

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


All Articles