Kivy. Xamarin Bereaksi Asli. Tiga kerangka kerja - satu percobaan (bagian 3)


Tugas membandingkan kerangka kerja adalah tugas yang sangat tanpa pamrih, preferensi pengembang berbeda, teknologi berubah sangat cepat. Terlalu cepat Artikel ini akan menjadi usang bahkan sebelum saya mengklik tombol publikasikan.


Ada upaya untuk membandingkan, misalnya, sekitar lima tahun yang lalu, para lelaki (Colin Eberhardt dan Chris Price) mengilhami sejumlah pengembang untuk membuat aplikasi untuk mencari real estat menurut TK yang disusun dengan jelas. Idenya keren, kami bahkan berpartisipasi dan membuat versi aplikasi ini di DevExtreme . Tetapi dalam hal dukungan, proyek seperti itu adalah neraka dan sekarang proyek Property Cross mewakili lapisan historis tertentu yang menyebabkan nostalgia dan perasaan hangat, tetapi hampir tidak praktis digunakan.

Jika kita hanya mengambil dunia js, yaitu, proyek todomvc yang lebih hidup yang hanya membandingkan bagian js, tanpa mengemasnya dalam ponsel, desktop, atau aplikasi apa pun. Proyek ini hidup dan didukung. Kemungkinan besar, masih ada contoh sangat keren yang tidak kami perhatikan di Google saat kami menyiapkan artikel, tetapi kami tidak akan kecewa karenanya.

Eksperimen kami kurang ambisius dan hanya menunjukkan bagian teknologi saat ini, bahkan sebagian kecil saja. Berikut ini tautan ke artikel percobaan pertama dan kedua .

Bacaan lebih lanjut adalah artikel ketiga tentang cara membuat aplikasi pada React Native menurut TK. Ini sangat mirip dengan ratusan, dan mungkin ribuan, menceritakan kembali dokumentasi tentang cara membuat aplikasi di React Native. Pembaca yang budiman, saya memperingatkan Anda, hati nurani saya jelas.

Ingat TK


Secara umum, ini dapat dilihat sepenuhnya di artikel pertama. Tapi saya akan menambahkan gambar apa yang harus dihasilkan pada akhirnya. Ada beberapa foto.
gambar

Sedikit peralatan. Apa itu Bereaksi Asli?


React Native adalah kerangka kerja untuk membuat aplikasi mobile lintas platform dari Facebook. Seperti dalam Bereaksi "reguler" untuk web, aplikasi UI dirakit dari batu bata - komponen yang merespons perubahan status (keadaan) dan properti yang diteruskan ke mereka (properti), tetapi, tidak seperti web, dirender ke dalam kontrol asli.

Idealnya, prinsip-prinsip kekebalan dan fungsi murni digunakan, yang memastikan kesederhanaan dan isolasi pengujian. Dan di sini perlu dicatat bahwa Bereaksi itu sendiri sangat sederhana, dan kesederhanaan ini masuk ke bagian ponsel.

Pengaya tambahan dalam kode asli dan JS merapikan perbedaan antar platform jika memungkinkan. Bahkan, React Native menyediakan beberapa penyatuan properti untuk komponen di setiap sistem operasi.

Sebagai contoh, ScrollView, dan HorizontalScrollView adalah 2 komponen berbeda di Android. Dan di iOS UIScrollView, yang mendukung gulir horizontal dan vertikal. Dan dalam React Native kita akan menggunakan kode lintas-platform berikut:

<ScrollView horizontal={true}/> 

Dengan pendekatan yang kompeten, kami mendapatkan aplikasi asli "jujur" yang berjalan di iOS dan Android.

Di dunia yang ideal, ketika berkembang dalam React Native, Anda tidak perlu menulis dalam Java atau Objective-C. Tetapi ada peluang seperti itu ketika Anda perlu mengimplementasikan komponen yang melampaui kemampuan React Native.

Pengembang dari Airbnb banyak bermain dengan ini, dan kita bisa melihat banyak implementasi yang layak di komunitas bereaksi yang sebelumnya ada di repositori mereka. Misalnya, Lottie adalah perpustakaan untuk mengimpor animasi dari Adobe After Effects, atau peta lintas platform .

Kode JS dalam aplikasi dijalankan pada mesin JavaScriptCore . Komunikasi antara kode asli dan JS dilakukan dengan menggunakan jembatan asinkron (jembatan), yang memungkinkan Anda untuk mentransfer properti (alat peraga), memicu peristiwa (peristiwa) dan panggilan balik.

Gambar diambil dari dokumentasi React Made Native Easy yang luar biasa . (Sangat merekomendasikan membaca.)

Selama proses pembuatan, babel model-baru digunakan untuk mengonversi kode JS, ini memungkinkan Anda untuk menggunakan sintaks ES6 baru, serta beberapa fitur ES8 (misalnya, menunggu async). Jika Anda, pembaca yang saya kasihi, adalah pengembang js, Anda mengerti betapa bagusnya itu ketika ada operator yang menyebar dan seberapa buruk itu ketika tidak ada.

Untuk tata letak halaman, teknologi flexbox digunakan, diimplementasikan oleh mesin Yoga lintas-platform. Ini memiliki perbedaan dari flexbox browser, tetapi mereka tidak signifikan dan terutama berkaitan dengan default. Tentu saja, ada nuansa, tetapi Anda akan beruntung, dan semuanya hanya akan sesuai dengan dokumentasi.

Mempersiapkan dan menggunakan tumpukan. Terminal tabung


Untuk bekerja dengan RN, kita perlu Node.js dan manajer paket npm, yang dibundel. Tidak perlu, tetapi sangat diinginkan untuk menginstal aplikasi Expo di perangkat Anda. Ini akan memungkinkan Anda untuk meluncurkan proyek kami di ponsel Anda, serta membangun dan menjalankan aplikasi iOS ketika Anda tidak memiliki macOS.

Ayo buat aplikasi baru. Untuk melakukan ini, gunakan paket create-react-native-app .

Di terminal, jalankan:

 npm install -g create-react-native-app create-react-native-app notes cd notes npm run start 

Pindai kode QR menggunakan Expo atau masukkan tautan dari terminal, atau bahkan kirim tautan ke telepon Anda, langsung dari terminal.

Saya biasanya memiliki kecurigaan bahwa pengembang cli untuk reaksi asli memiliki pria tua berambut abu-abu yang menemukan mainan roguelike tanpa ui ketika hanya ada terminal, dan bukannya kartu video top-end, hanya imajinasi Anda.

Tapi kami, sementara itu, baru saja membuat dan meluncurkan aplikasi "Hello World".

Dan keseluruhan "Hello World" -a tidak cukup. Analisis TK


Menurut pernyataan kerja, struktur data aplikasi akan

 Note: { userName: string, avatar: string, editTime: string, text: string } Project: { name: string, notes: Array<Note> } Projects: Array<Project> 

Untuk bekerja dengan data seperti itu, saya akan mengambil beberapa solusi yang sangat modis berdasarkan CQRS. Ini akan memungkinkan menjaga integritas data, memberikan kecepatan membaca yang tinggi dengan kemampuan untuk mengatur ulang proyeksi, serta penyebaran cepat ke cloud dengan satu perintah. Seperti Resolve , yang dikembangkan oleh rekan kami.

Tetapi saya tidak akan menerimanya, kami memiliki eksperimen sederhana, tanpa backend. Dan untuk kesederhanaan saya akan menggunakan arsitektur fluks , khususnya implementasinya - redux . Data dari status aplikasi datang ke komponen sebagai alat peraga. Komponen dapat memanggil tindakan untuk memperbarui data.

Aplikasi akan memiliki 3 layar, semua sesuai dengan ToR:
  • daftar proyek - Proyek,
  • halaman proyek terperinci dengan daftar catatan - Proyek,
  • halaman catatan rinci - Catatan


Untuk navigasi antar layar saya akan menggunakan pustaka navigasi reaksi standar. Angka-angka di dekat grafik pada halaman perpustakaan menunjukkan berapa kali itu diunduh per minggu. Sekarang ada sekitar 100 ribu, per minggu. Bagus bahwa saya bukan satu-satunya yang memilih perpustakaan untuk navigasi. Dan ya, Anda dapat melihat digit dari paket npm lainnya yang saya sebutkan di artikel ini untuk secara kasar memahami jumlah pengguna teknologi ini pada waktu tertentu.

Buat aplikasi


Untuk Bereaksi Asli, komponen Aplikasi dari file App.js adalah titik masuk ke aplikasi.

 export default class App extends Component { render() { return ( <Provider store={store}> <Navigator /> </Provider> ) } } 

Simpan dengan data dan status aplikasi terhubung oleh komponen Penyedia dari perpustakaan react-redux. Ini memberikan penerusan data untuk komponen bersarang.

Buat navigator untuk transisi antar layar dalam aplikasi. Ini jelas mencerminkan struktur aplikasi, dinyatakan dalam percobaan, dan menggambar transisi animasi antara layar untuk setiap platform.

 const Navigator = createStackNavigator({ Projects: { screen: Projects }, Project: { screen: Project }, Note: { screen: Note } }) 

Layar navigator adalah komponen - wadah. Mereka mendapatkan data dari status aplikasi.

Daftar Proyek - Proyek


Di layar dengan daftar proyek akan ada daftar dan tombol untuk menambahkan proyek - di header jendela di sebelah kanan. Kami akan membuat proyek baru di layar Proyek.

Untuk navigasi, kami menggunakan objek navigasi, yang diteruskan ke properti komponen induk - navigator.

 export class Projects extends PureComponent { static navigationOptions = ({ navigation }) => ({ headerRight: ( <AddButton onPress={() => navigation.navigate('Project')} /> ) }) navigateProject = project => { this.props.navigation.navigate('Project', { projectId: project.id, name: project.name }) } render() { return ( <ProjectList projects={this.props.projects} onPressProject={this.navigateProject} /> ) } } 

Untuk menampilkan daftar proyek, kami akan menggunakan FlatList - daftar lintas platform dengan virtualisasi:

 export class ProjectList extends PureComponent { static propTypes = { projects: ProjectsType, onPressProject: PropTypes.func } renderItem = ({ item }) => ( <ProjectListItem project={item} onPressProject={this.props.onPressProject} /> ) render() { return ( <FlatList data={this.props.projects} keyExtractor={item => item.id} renderItem={this.renderItem} /> ) } } 

Untuk setiap elemen, kami menetapkan kunci unik - di sini kami memiliki id elemen. Ini diperlukan agar reaksi dapat membedakan antara elemen dalam daftar dan hanya memperbarui yang telah berubah.

Tambahkan komponen ke item daftar.

 export class ProjectListItem extends PureComponent { static propTypes = { project: ProjectType, onPressProject: PropTypes.func } onPressProject = () => { const { project, onPressProject } = this.props onPressProject(project) } render() { return ( <TouchableOpacity onPress={this.onPressProject}> <View style={styles.project}> <Text style={styles.name}>{this.props.project.name}</Text> </View> </TouchableOpacity> ) } } 

TouchableOpactity - pembungkus yang merespons klik. Ketika diklik, komponen bersarang menjadi lebih transparan.
Lihat - analog div untuk web - komponen dasar markup.
Teks - wadah untuk teks.

Tambahkan gaya:

 const styles = StyleSheet.create({ project: { paddingVertical: 30, paddingHorizontal: 15, backgroundColor: 'white', borderBottomWidth: StyleSheet.hairlineWidth, borderColor: 'gray' }, name: { fontSize: 16 } }) 

Sintaks gaya menyerupai css, perbedaan utamanya adalah Anda dapat menyesuaikan dgn mode hanya komponen itu sendiri (misalnya, Anda tidak dapat mengatur ukuran font untuk seluruh aplikasi, hanya untuk komponen Teks tertentu)


Halaman proyek terperinci dengan daftar catatan - Proyek


Demikian pula, buat halaman detail. Perbedaannya hanya di hadapan judul di navigator dan input tambahan. Di navigator, tetapkan judul - nama proyek. Jika id proyek tidak ditentukan, kami akan menawarkan untuk memasukkan nama proyek dan membuat yang baru.

 export class Project extends PureComponent { static navigationOptions = ({ navigation }) => { const projectId = navigation.getParam('projectId') return { title: navigation.getParam('name', ''), headerRight: ( <AddButton onPress={() => navigation.navigate('Note', { projectId })} /> ) } } removeNote = noteId => { const { projectId, removeNote } = this.props removeNote(projectId, noteId) } navigateNote = noteId => { const { projectId, navigation } = this.props navigation.navigate('Note', { noteId, projectId }) } createProject = name => { const newProjectId = shortid.generate() this.props.navigation.setParams({ projectId: newProjectId, name }) this.props.addProject(newProjectId, name) } render() { const { projectId, project } = this.props if (!projectId) { return ( <ProjectNameInput onSubmitEditing={this.createProject} /> ) } return ( <NoteList notes={project.notes} onNavigateNote={this.navigateNote} onRemoveNote={this.removeNote} /> ) } } 

Halaman proyek adalah daftar catatan. Menurut ToR untuk setiap catatan ada menu konteks dengan pengeditan dan penghapusan. Anda juga dapat menghapus catatan dengan babatan. Ada daftar terpisah di React Native, dengan kemampuan untuk menggesek - SwipeableFlatList.

 <SwipeableFlatList data={this.props.notes} bounceFirstRowOnMount={false} keyExtractor={item => item.id} maxSwipeDistance={MAX_SWIPE_DISTANCE} renderQuickActions={this.renderQuickActions} renderItem={this.renderItem} /> 

Saat menghapus catatan, kami akan meminta konfirmasi, untuk ini kami akan memanggil sistem peringatan standar

 onRemoveNote = noteId => { Alert.alert( 'Remove Note', 'Do you want to remove note ?', [ { text: 'Cancel', onPress: () => {}}, { text: 'Remove', onPress: () => this.props.onRemoveNote(noteId) } ] ) } 



Ada poin yang menarik untuk menu konteks. Berbeda dengan lansiran, implementasinya di RN untuk Android dan iOS berbeda.

Untuk android, gunakan menu popup

 showPopupMenu = () => { const button = findNodeHandle(this._buttonRef) UIManager.showPopupMenu( button, [ 'Edit', 'Delete' ], e => console.error(e), (e, i) => this.onPressMenu(i) ) } 

Untuk iOS - actionSheet

 showActionSheet = () => { ActionSheetIOS.showActionSheetWithOptions({ options: [ 'Edit', 'Delete', 'Cancel' ], destructiveButtonIndex: 1, cancelButtonIndex: 2 }, this.onPressMenu ) } 

Ada beberapa cara untuk membagi kode khusus platform. Kami akan menggunakan objek Platform.

 onOpenMenu = Platform.select({ android: this.showPopupMenu, ios: this.showActionSheet }) 



Halaman Catatan Rinci - Catatan


Halaman catatan juga cukup primitif. Tetapi, tidak seperti yang sebelumnya, kami menggunakan status untuk menyimpan hasil input pengguna menengah.

 export class Note extends PureComponent { static navigationOptions = ({ navigation }) => ({ headerRight: ( <SaveButton onPress={navigation.getParam('onSaveNote')} /> ) }) state = { noteText: '' } componentDidMount() { this.props.navigation.setParams({ onSaveNote: this.onSaveNote }) } onSaveNote = () => { Keyboard.dismiss() const { projectId, noteId, note, navigation, addNote, editNote } = this.props const { noteText } = this.state if (!noteId) { const newNoteId = shortId.generate() navigation.setParams({ noteId: newNoteId }) addNote(projectId, newNoteId, noteText) } else if (noteText && noteText !== note.text) { editNote(projectId, noteId, noteText) } } onChangeNote = noteText => { this.setState({ noteText }) } render() { const initialTextValue = this.props.note ? this.props.note.text : '' const noteText = this.state.noteText || initialTextValue return ( <NoteDetail noteText={noteText} onChangeNoteText={this.onChangeNote} /> ) } } 

Layar detail note - komponen "konyol" klasik - melaporkan perubahan teks dan menunjukkan teks yang dilewati induknya

 export class NoteDetail extends PureComponent { static propTypes = { noteText: PropTypes.string, onChangeNoteText: PropTypes.func } render() { const { noteText, onChangeNoteText } = this.props return ( <View style={styles.note}> <TextInput multiline style={styles.noteText} value={noteText} placeholder="Type note text here ..." underlineColorAndroid="transparent" onChangeText={onChangeNoteText} /> </View> ) } } 



Secara total, kami menerima aplikasi seperti di TK. Eksperimen selesai. Kode aplikasi dapat dilihat di repositori umum

Total, Pro dan Kontra dari React Native


Pro:


React Native dikenal dan dimengerti oleh pengembang yang akrab dengan React dan kerangka Node.js dan npm. Dimungkinkan untuk menggunakan semua pendekatan dan perpustakaan, seperti untuk Bereaksi biasa.

Sejumlah besar paket js dari npm. Kemungkinan besar, sebagian besar tugas standar telah diselesaikan dan mungkin di bawah lisensi MIT.

Komunitas besar Baik pengembang individu dan perusahaan besar telah menggunakan RN untuk pengembangan, dan terus menggunakannya.

Banyak set komponen UI yang sudah jadi, seperti NativeBase , React Native Elements , perpustakaan dari perusahaan besar seperti Facebook, Airbnb, Wix.com.

Hapus toolkit untuk pengembangan aplikasi yang nyaman dari Hello World ke Instagram .

Cons:


Aplikasi dimulai lebih lambat dari yang asli dan ada beberapa kesulitan debugging. Kode JS di dan tanpa debugger berjalan di mesin yang berbeda. Airbnb menulis dengan sangat baik tentang masalah ini dalam serangkaian artikel tentang mengapa mereka meninggalkan React Native dalam pengembangan.

Karena toolkit terdiri dari banyak paket yang dikembangkan secara terpisah, ada kemungkinan konflik versi dan istirahat.

Tidak semuanya bisa dilakukan tanpa kode asli. Dan ketika Anda membuat perubahan pada kode asli, Anda kehilangan kemampuan untuk menggunakan Expo dan memaksa diri Anda untuk membangun aplikasi menggunakan alat pengembangan asli standar.

Terima kasih banyak kepada Mirimon dan HeaTTheatR yang telah mengundang saya untuk berpartisipasi dalam percobaan ini. Itu mengasyikkan. Terakhir, tambahkan suara.

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


All Articles