Selami React Native untuk Pengembangan Android

Diterbitkan: 2022-03-11

Beberapa tahun yang lalu, seorang rekan kerja saya memberi tahu saya tentang React Native. Saya sangat skeptis. Saya berpendapat bahwa ini hanyalah kerangka kerja lintas platform yang tidak akan pernah berfungsi dalam kehidupan nyata – sedikit yang saya tahu betapa salahnya saya.

Tahun-tahun berlalu dan keterampilan React Native menjadi sangat diminati. Karena sudah lama saya mempelajari sesuatu yang baru, saya pikir mengapa tidak mencobanya? Hari ini, saya advokat React Native yang hebat.

Kontra:

  • Anda tidak dapat menggunakan Android Studio lagi
  • React Native tidak dapat digunakan untuk semua aplikasi atau fitur
  • React Native adalah kerangka kerja baru dan pembaruan dapat memiliki efek negatif pada basis kode Anda saat ini
  • JavaScript bukan bahasa yang diketik secara ketat
  • React Native membutuhkan mesin JavaScript untuk berjalan, yang mungkin membuatnya kurang berkinerja

Kelebihan:

  • Mudah untuk dipelajari
  • Basis kode bersama antara aplikasi Android dan iOS, dengan hanya sedikit penyesuaian yang diperlukan untuk menyesuaikan pengalaman platform
  • Muat ulang langsung dan panas, artinya tidak ada lagi waktu pembuatan yang tak terbatas
  • Komponen asli untuk kedua platform
  • Terus meningkat
  • Komunitas yang tumbuh secara aktif
  • Banyaknya perpustakaan
  • Expo menghilangkan kebutuhan untuk memiliki Mac untuk dikembangkan di iOS
  • Pengurangan sumber daya tenaga kerja—meskipun Anda mungkin masih memerlukan beberapa pengembangan asli Android/iOS, hal itu akan jarang terjadi.

Saya dapat melanjutkan, tetapi mari kita berhenti di sini dan beralih ke topik posting blog ini. Dalam posting ini, saya akan membuat empat aplikasi Android yang didukung oleh React Native:

  1. Penghitung dasar dengan tombol untuk menambah dan mengurangi penghitung
  2. Aplikasi untuk mencari subreddit r/pics
  3. Halaman login umum
  4. Aplikasi untuk menelusuri subreddit r/pics

IDE

Seperti yang saya sebutkan di atas, tidak mungkin kita bisa menggunakan Android Studio untuk pengembangan React Native. Kami butuh pengganti. React Native mungkin dapat dikembangkan di editor teks modern mana pun yang tersedia di luar sana (Atom, VS Code, Sublime Text, Brackets, dll.) tetapi karena kami hadir dengan pengalaman Android Studio, favorit saya adalah WebStorm yang dibuat oleh perusahaan yang sama. Meskipun WebStorm adalah aplikasi berbayar ($129 per tahun), Anda dapat menginstal versi Early Access-nya. Pembuatan EAP dari WebStorm gratis dan cukup stabil. Jika Anda lebih suka editor yang sepenuhnya gratis, gunakan VS Code. Microsoft bahkan mengembangkan plugin React Native yang luar biasa untuk itu dan itu bekerja dengan sangat baik.

Membuat Proyek Baru

Prasyarat: Android SDK, Node, dan React Native terinstal di komputer Anda.

Ada dua cara untuk membuat proyek React Native baru.

  1. Cara konvensional. Baik dengan GUI WebStorm atau dengan perintah terminal: react-native init AwesomeToptalProject
  2. Cara yang lebih mudah "Buat React Native App". create-react-native-app AwesomeToptalProject

Jika Anda menggunakan create-react-native-app , proyek yang dibuat akan di-bootstrap dengan expo. Saya tidak akan membahas detailnya, tetapi pada dasarnya, ini berarti Anda tidak perlu menginstal Xcode untuk menjalankan aplikasi di iOS. Juga lebih mudah untuk membuat klien selalu up-to-date melalui fungsi expo.io dan beberapa fitur lainnya. Tetapi Anda tidak dapat menambahkan kode asli. Jadi, jika Anda mengembangkan fitur tertentu, Anda mungkin perlu mengeluarkan aplikasi dari pameran dan menggunakan proyek React Native biasa.

Saya akan menggunakan cara pertama.

Mari kita jalankan proyeknya. Pertama, buka emulator atau sambungkan perangkat. Jika Anda membuat proyek dengan GUI WebStorm, yang perlu Anda lakukan hanyalah memilih konfigurasi. Di sudut kanan atas WebStorm, klik tarik-turun di sebelah kiri tombol Jalankan, pilih Android, dan klik Jalankan atau Debug. Jika Anda membuat proyek dengan Terminal, Anda dapat menambahkan konfigurasi React Native baru atau menjalankannya menggunakan Terminal:

 cd AwesomeToptalProject react-native run-android

Jika semuanya berjalan dengan baik, Anda akan disambut dengan layar berikut:

Tata letak yang dihasilkan

Struktur dan Pengaturan Dasar

Item penting di dalam proyek adalah:

  • android - Proyek Android Studio telah dikonfigurasi dengan dukungan React Native.
  • ios - Proyek Xcode telah dikonfigurasi dengan dukungan React Native.
  • node_modules - Folder yang berisi framework React Native dan library Javascript lainnya.
  • index.js - Titik masuk untuk aplikasi kita.
  • App.js - Komponen awal dimuat.

Mari buat folder “src” di dalam root proyek dan pindahkan App.js ke sana. Anda harus memperbarui impor index.js agar sesuai dengan lokasi App.js baru.

 import App from './src/App';

Hapus semua yang ada di dalam App.js dan rekatkan kode ini:

 import React from 'react'; import {Text} from 'react-native'; export default class App extends React.Component { render() { return ( <Text>Hello TopTal</Text> ); } }

Kode yang kami tempel cukup mudah. Kami membuat App kelas (anak dari React.Component ) yang menggantikan metode render() dan mengembalikan komponen Text . React.Component adalah kelas dasar untuk membangun UI menggunakan JSX. Pengubah export default membuat kelas menjadi public .

Kami sekarang siap untuk mulai mendesain tata letak kami.

Tata letak dengan Flexbox

Flexbox mirip dengan LinearLayout , tetapi Flexbox jauh melampaui kemampuan LinearLayout .

Cuplikan BEJ ini:

 <View style={{ flex: 1, flexDirection: 'row' }}> <View style={{ width: 100, height: 100, backgroundColor: '#9575CD' }}/> <View style={{ width: 100, height: 100, backgroundColor: '#7E57C2' }}/> <View style={{ width: 100, height: 100, backgroundColor: '#673AB7' }}/> </View>

Membuat tata letak ini:

Tata letak yang dihasilkan


Sementara XML ini:

 <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal"> <View android:layout_width="100dp" android:layout_height="100dp" android:background="#9575CD" /> <View android:layout_width="100dp" android:layout_height="100dp" android:background="#7E57C2" /> <View android:layout_width="100dp" android:layout_height="100dp" android:background="#673AB7" /> </LinearLayout>

Membuat ini:

Tata letak yang dihasilkan

Kode JSX terlihat familier, ya?! Mari buat "kamus" (atau lembar contekan) untuk tata letak menggunakan yang terlihat serupa di JSX dan Android XML.

Harap dicatat bahwa fungsinya tidak selalu sama. Saya mencoba membantu pemula React Native untuk memahami ide sistem tata letak di React Native. Silakan lihat panduan resmi untuk informasi rinci.

Pertimbangkan properti BEJ ini:

 flex: 1

Ini setara dengan ini:

 android:layout_width="match_parent" android:layout_height="match_parent"

Cuplikan BEJ ini:

 <View style={{flex: 1, flexDirection: 'row'}}> <View style={{ width: 100, height: 100, backgroundColor: '#9575CD'}}/> <View style={{ width: 100, height: 100, backgroundColor: '#7E57C2'}}/> <View style={{ width: 100, height: 100, backgroundColor: '#673AB7'}}/> </View>

Dan XML ini:

 <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal"> <View android:layout_width="100dp" android:layout_height="100dp" android:background="#9575CD" /> <View android:layout_width="100dp" android:layout_height="100dp" android:background="#7E57C2" /> <View android:layout_width="100dp" android:layout_height="100dp" android:background="#673AB7" /> </LinearLayout>

Keduanya menghasilkan output ini:

Tata letak yang dihasilkan


Demikian pula BEJ ini:

 <View style={{flex: 1, flexDirection: 'column'}}> <View style={{ width: 100, height: 100, backgroundColor: '#9575CD'}}/> <View style={{ width: 100, height: 100, backgroundColor: '#7E57C2'}}/> <View style={{ width: 100, height: 100, backgroundColor: '#673AB7'}}/> </View>

Dan XML ini:

 <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <View android:layout_width="100dp" android:layout_height="100dp" android:background="#9575CD" /> <View android:layout_width="100dp" android:layout_height="100dp" android:background="#7E57C2" /> <View android:layout_width="100dp" android:layout_height="100dp" android:background="#673AB7" /> </LinearLayout>

Hasilkan ini:

Tata letak yang dihasilkan


Untuk mencapai posisi yang tepat di dalam wadah, kita paling sering akan menggunakan kombinasi flexDirection , alignItems , dan justifyContent .

BEJ ini:

 <View style={{flex: 1, flexDirection: 'column', alignItems: 'center'}}> <View style={{ width: 100, height: 100, backgroundColor: '#9575CD'}}/> <View style={{ width: 100, height: 100, backgroundColor: '#7E57C2'}}/> <View style={{ width: 100, height: 100, backgroundColor: '#673AB7'}}/> </View>

Dan XML ini:

 <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center_horizontal" android:orientation="vertical"> <View android:layout_width="100dp" android:layout_height="100dp" android:background="#9575CD" /> <View android:layout_width="100dp" android:layout_height="100dp" android:background="#7E57C2" /> <View android:layout_width="100dp" android:layout_height="100dp" android:background="#673AB7" /> </LinearLayout>

Akan menghasilkan tata letak ini:

Tata letak yang dihasilkan


BEJ ini:

 <View style={{flex: 1, flexDirection: 'column', justifyContent: 'center'}}> <View style={{ width: 100, height: 100, backgroundColor: '#9575CD'}}/> <View style={{ width: 100, height: 100, backgroundColor: '#7E57C2'}}/> <View style={{ width: 100, height: 100, backgroundColor: '#673AB7'}}/> </View>

Dan XML ini

 <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center_vertical" android:orientation="vertical"> <View android:layout_width="100dp" android:layout_height="100dp" android:background="#9575CD" /> <View android:layout_width="100dp" android:layout_height="100dp" android:background="#7E57C2" /> <View android:layout_width="100dp" android:layout_height="100dp" android:background="#673AB7" /> </LinearLayout>

Akan menghasilkan tata letak ini:

Tata letak yang dihasilkan


BEJ ini:

 <View style={{flex: 1, flexDirection: 'row', justifyContent: 'center'}}> <View style={{ width: 100, height: 100, backgroundColor: '#9575CD'}}/> <View style={{ width: 100, height: 100, backgroundColor: '#7E57C2'}}/> <View style={{ width: 100, height: 100, backgroundColor: '#673AB7'}}/> </View>

Dan XML ini:

 <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center_horizontal" android:orientation="horizontal"> <View android:layout_width="100dp" android:layout_height="100dp" android:background="#9575CD" /> <View android:layout_width="100dp" android:layout_height="100dp" android:background="#7E57C2" /> <View android:layout_width="100dp" android:layout_height="100dp" android:background="#673AB7" /> </LinearLayout>

Akan menghasilkan tata letak ini:

Tata letak yang dihasilkan


BEJ ini:

 <View style={{flex: 1, flexDirection: 'row', justifyContent: 'center', alignItems: 'center'}}> <View style={{ width: 100, height: 100, backgroundColor: '#9575CD'}}/> <View style={{ width: 100, height: 100, backgroundColor: '#7E57C2'}}/> <View style={{ width: 100, height: 100, backgroundColor: '#673AB7'}}/> </View>

dan XML ini:

 <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="vertical"> <View android:layout_width="100dp" android:layout_height="100dp" android:background="#9575CD" /> <View android:layout_width="100dp" android:layout_height="100dp" android:background="#7E57C2" /> <View android:layout_width="100dp" android:layout_height="100dp" android:background="#673AB7" /> </LinearLayout>

Akan menghasilkan tata letak ini:

Tata letak yang dihasilkan


Pelajaran yang bisa dipelajari: jika kita memiliki flexDirection: row', alignItems works on Y axis and justifyContent works on X axis. Everything is mirrored for works on X axis. Everything is mirrored for flexDirection: column' - justifyContent memengaruhi sumbu Y dan alignItems memengaruhi sumbu Y.

justifyContent: 'mulai fleksibel' gravitasi="mulai|kiri"
alignItems: 'mulai fleksibel' gravitasi="mulai|kiri"
justifyContent: 'flex-end' gravitasi="akhir|kanan"
alignItems: 'akhir fleksibel' gravitasi="akhir|kanan"

Cobalah sendiri. Tetapkan nilai justifyContent ke space-around , space-between , dan space-evenly .

Manajemen Negara

Untuk memperbarui status aplikasi, Anda akan menggunakan variabel state React. Setiap kali state diperbarui, render() dipanggil.

Salin kode di bawah ini ke aplikasi Anda:

 import React from 'react'; import {Button, Text, View} from 'react-native'; export default class App extends React.Component { /* Initialize state object with variable 'number' set to 0 and variable name with value of empty string */ state = {number: 0}; render() { return ( <View style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', flex: 1, padding: 20 }}> <Button title='Decrement' color='#e57373' onPress={() => this.decrement()}/> <Text> {/* Text will be automatically updated whenever state.number has changed value */} Value = {this.state.number} </Text> <Button title='Increment' color='#64B5F6' {/* Set listener for click */} onPress={() => this.increment()}/> </View> ); } //Declaration of decrement function decrement() { //To update the state we need invoke this.setState //with new value for variable 'number' this.setState({number: this.state.number - 1}); } increment() { this.setState({number: this.state.number + 1}); } } 
Aplikasi pengurangan akhir

Jika Anda mengklik tombol PENURUNAN dan PENINGKATAN, Anda akan melihat bahwa teks diperbarui secara otomatis untuk Anda. Tidak perlu secara eksplisit menggunakan textView.setText("Value " + number) .

Fungsionalitas status berguna karena berbagai alasan:

  • Kemudahan mendapatkan nilai—Anda selalu tahu di mana dan bagaimana mendapatkan nilai untuk variabel tertentu.
  • Data tidak terikat pada widget tertentu.
  • Memiliki beberapa widget bergantung pada perubahan nilai umum.

Membuat Aplikasi Pencarian untuk /r/pics

Sekarang setelah kita menguasai dasar-dasarnya, mari kita buat sesuatu yang sedikit lebih kompleks: aplikasi pencarian untuk /r/pics. Reddit menyediakan titik akhir API JSON langsung, jadi kita tidak perlu melakukan pencarian sampingan untuk mendapatkan autentikasi agar berfungsi dengan benar.

React Native menyediakan Fetch API bawaan. Karena sebagian besar dari kita mungkin terbiasa dengan Retrofit dan kemudahan penggunaannya, kita akan menggunakan axios . Anda dapat menginstal axios melalui perintah terminal

menggunakan yarn (Metode pilihan saya):

yarn add axios

atau menggunakan npm :

npm install axios

Impor:

 import React from 'react'; import { TextInput, View, Text, Image, ActivityIndicator, Platform, StyleSheet } from 'react-native'; import axios from 'axios'; TextInput = EditText, ActivityIndicator = ProgressBar Platform - Platform detecting module StyleSheet - Module for creating stylesheets and moving them away from JSX

Buat kelas:

 export default class App extends React.Component { }

Untuk menginisialisasi status. Kami akan membutuhkan:

  • memuat - Untuk menampilkan bilah kemajuan.
  • error - Untuk menunjukkan jika ada kesalahan yang muncul saat membuat permintaan REST API.
  • imgUrl - Untuk melihat pratinjau gambar yang dicari.
  • teks - permintaan pencarian.
 state = {text: '', loading: false, error: null, imgUrl: null};

Tambahkan kode JSX. Kami memiliki tata letak vertikal dengan komponen TextInput dan Image .

 render() { return ( //Predefined style. See below <View style={styles.containerStyle}> {/* returnKeyType ~ imeOptions onSubmitEditing ~ et.OnEditorActionListener */} <TextInput style={styles.textInputStyle} placeholder="Enter text to search an image" returnKeyType='search' autoFocus={true} onChangeText={(text) => this.setState({text})} onSubmitEditing={() => this.searchPicture()}/> {/* Render error Image component if this.state.imgUrl is not equal to null */} { this.state.imgUrl && <Image source={{uri: this.state.imgUrl}} style={{flex: 1}}/> } </View> ); }

Barang baru:

 onChangeText={(text) => this.setState({text})} onSubmitEditing={() => this.searchPicture()} { this.state.imgUrl && <Image source={{uri: this.state.imgUrl}} style={{flex: 1}}/> }

Metode pertama melakukan pekerjaan yang mirip dengan EditText dengan komponen TextWatcher . Jujur saja, itu jauh lebih bagus di React Native.

Metode kedua dipanggil saat tombol kembali ditekan pada keyboard ( et.OnEditorActionListener ) setelah memicu searchPicture() .

Gambar dirender ketika imgUrl tidak nol atau tidak ditentukan karena operator '&&' tidak memeriksa argumen kedua jika yang pertama sudah salah.

Anda mungkin bertanya-tanya mengapa this.state.imgUrl salah. Nah, saat menggunakan operator logika dalam JavaScript, apa pun kecuali '' (string kosong), 0 , false , null , atau undefined adalah true. Tidak perlu pemeriksaan khusus.

 searchPicture() { //Default state this.setState({loading: true, error: null, imgUrl: null}); axios.get('https://www.reddit.com/r/pics/search.json', { params: { //the get param map restrict_sr: 'on', //search only /r/pics limit: 1, //limit to one search item sort: 'new', //sort by creation date q: this.state.text //our search query } }).then(response => { //promise is resolved and 'then' block is triggered //set state with new values this.setState({ imgUrl: response.data.data.children[0] .data.preview.images[0].source.url, error: null, loading: false }) }).catch(error => {//Some error occurred //set error this.setState({error: error.message, loading: false, imgUrl: null}) }) }

Ini dia. Aplikasi harus bekerja seperti yang diharapkan sekarang. Masukkan string pencarian dan tekan kembali.

Aplikasi pencarian reddit terakhir

Karena aplikasi kita juga siap untuk merender ActivityIndicator dan error, kita perlu menambahkan beberapa kode lagi setelah komponen Image :

 { //Separate method this.renderProgress() } {/* Render error Text component if this.state.error is not equal to null */} { this.state.error && <Text style={{margin: 16, color: 'red'}}> {this.state.error} </Text> }

Anda juga dapat memindahkan komponen render di luar metode render() utama:

 renderProgress() { //If this.state.loading is true //return View containing a progressbar //View takes style array if (this.state.loading === true) { return ( <View style={ [styles.containerStyle, {justifyContent: 'center'}]}> <ActivityIndicator color='#e57373'/> </View> ); } }

Yang tersisa hanyalah gaya. Letakkan ini di luar kelas App .

 const styles = StyleSheet.create({ containerStyle: { flexDirection: 'column', flex: 1, //Since React Native is cross platform //let's handle both platforms. //Add top margin to fix status bar overlap marginTop: Platform.OS === 'ios' ? 20 : 0, }, textInputStyle: { marginLeft: 16, marginRight: 16, height: Platform.OS === 'ios' ? 30 : undefined } });

Kita sekarang dapat menambahkan beberapa tweak lagi seperti membuka soft keyboard secara otomatis saat aplikasi diluncurkan.

Harap dicatat ada cara yang lebih mudah untuk membuat TextInput secara otomatis fokus ( autoFocus={true} prop ), tetapi demi contoh ini, kami tidak akan menggunakannya.

Tambahkan referensi ke TextInput dengan prop:

ref={ref => this.searchInput = ref}

Dan timpa metode siklus hidup componentDidMount() seperti ini:

 componentDidMount(){ this.searchInput.focus(); }

Muat ulang aplikasi dan keyboard secara otomatis terbuka untuk kami.

Metode Siklus Hidup Komponen

Kita telah membuat sebuah komponen, tetapi mari kita lihat masa pakai sebuah komponen.

Berikut alur siklus hidup React:

  • constructor() - Konstruktor selalu dipanggil saat aplikasi dijalankan
  • static _getDerivedStateFromProps_(props, state) - Dipanggil sebelum render dan setelah update. Mengembalikan objek untuk memperbarui status. Kembalikan nol untuk tidak memperbarui apa pun.
  • render() - Render diperlukan untuk setiap kelas React Component. Digunakan untuk merender View.
  • componentDidMount() - Dipanggil setelah komponen dirender dan dipasang ke pohon tampilan.
  • shouldComponentUpdate(nextProps, nextState) - Dipanggil setelah status atau props berubah. Pengembalian default ke true setelah setiap pembaruan status. Memanggil render() jika mengembalikan true.
  • getSnapshotBeforeUpdate(prevProps, prevState) - Dipanggil tepat sebelum output yang di-render di-commit.
  • componentDidUpdate(prevProps, prevState, snapshot) - Dipanggil setelah merender pembaruan baru. Itu tidak dipanggil setelah render() pertama.
  • componentWillUnmount() - Dipanggil sebelum komponen dilepas dan dihancurkan.

Bagan siklus hidup komponen

Komponen yang dapat digunakan kembali

Kita sering kali perlu membuat komponen yang dapat digunakan kembali saat mengerjakan proyek. Ada dua cara untuk membuat komponen:

  1. Membuat kelas yang memperluas React.Component . Metode ini harus digunakan jika kita membutuhkan metode siklus hidup.
  2. Dengan menulis fungsi yang mengembalikan View untuk sintaks yang lebih sederhana.

Karena kita telah membuat kelas Komponen, mari buat fungsi untuk instance ini.

Misalkan kita membutuhkan analog ke <CardView> . Buat folder "umum" di bawah direktori ./src .

Buat CardView.js .

 import React from "react"; import {View} from "react-native"; export default CardView = (props) => { return ( //Style will be merged from default containerStyle //and props.style. props.style attributes will override //values if parameters are same. <View style={{...styles.containerStyle, ...props.style}}> {/* props.children contain subviews add this line if the component is container */} {props.children} </View> ); }; const styles = { containerStyle: { borderRadius: 4, margin: 5, padding: 5, elevation: 5, shadowColor: 'black', shadowRadius: 5, shadowOpacity: 0.5, shadowOffset: {width: 0, height: 3}, backgroundColor: 'white' } };

LoginForm menggunakan tata letak CardView baru kami:

 import React from "react"; import {TextInput, Platform, Button, StyleSheet} from "react-native"; import CardView from "../common/components/CardView"; export default class LoginForm extends React._Component _{ render() { return ( //Override default style <CardView style={{ borderRadius: 4, backgroundColor: '#fff' }}> <TextInput placeholder="Email" style={styles.textInputStyle}/> <TextInput placeholder="Password" style={styles.textInputStyle} secureTextEntry={true}/> <Button color="#841584" title="Login" onPress={() => console.log("onLoginPress")} buttonStyle={styles.buttonStyle}/> </CardView> ); } } const styles = StyleSheet.create({ buttonStyle: { elevation: 5, height: 40 }, textInputStyle: { padding: 10, //Additional params to make //iOS inputs prettier ...Platform.select({ ios: { borderRadius: 2, marginTop: 5, backgroundColor: '#eeeeee' } }) } });

Impor kelas LoginForm di kelas App dan bungkus dengan View

 <View style={{flex: 1, justifyContent: 'center'}}> <LoginForm/> </View>

Jika Anda mengubah parameter dalam gaya, Anda bisa mendapatkan sesuatu yang terlihat jauh lebih bagus.

Aplikasi formulir login yang dihasilkan akhir

Navigasi

Navigasi ke pemandangan yang berbeda merupakan bagian penting untuk sebagian besar aplikasi. Kita akan membuat aplikasi browser Reddit /r/pics.

Membuat navigasi di React Native cukup mudah.

Prasyarat

  • Instal react-navigation dengan yarn atau npm
  • Instal axios dengan yarn atau npm

Mari kita mulai dengan membuat dua komponen yang berbeda.

Catatan: Sebagian besar kode di bawah ini seharusnya sudah Anda kenal. Saya akan menempelkan seluruh kelas.

PictureList.js:

 import React from 'react'; import { ActivityIndicator, FlatList, Image, Text, TouchableHighlight, View } from "react-native"; import axios from "axios"; import CardView from "../common/CardView"; export default class PictureList extends React.Component { state = {loading: true, error: null, posts: null}; componentDidMount() { axios.get('https://www.reddit.com/r/pics.json') .then(response => { this.setState({ posts: response.data.data.children, loading: false }) }).catch(error => { this.setState({ error: error.message, loading: false }) }) } render() { return ( <View style={{flex: 1, justifyContent: 'center'}}> // FlatList ~ ListView // data - DataSource for the List // renderItem - function returns View item // keyExtractor - Unique id for items {this.state.posts && <FlatList data={this.state.posts} renderItem={this.renderItem.bind(this)} keyExtractor={(item) => (item.data.id + '')}/>} {this.state.loading && <ActivityIndicator size="large" color="#f4511e"/>} </View> ); } navigateToPicture(title, url) { this.props.navigation.navigate('PicturePreview', { 'title': title, 'url': url }) } renderItem(item) { //Destructuring values from item //Read more 'ES6 destructuring' const {data} = item.item; const {title} = data; const {url} = data.preview.images[0].source; return ( //Clickable view <TouchableHighlight onPress={() => this.navigateToPicture(title, url)}> {/Reusing our CardView/} <CardView> <Image style={{height: 150}} source={{uri: url}}/> <Text style={{padding: 5}}>{title}</Text> </CardView> </TouchableHighlight> ) } }

PicturePreview.js :

 import React from 'react'; import {Image} from "react-native"; export default class PicturePreview extends React.Component { //Destructure navigation //Set title to header static _navigationOptions = ({navigation}) => ({ title: navigation.state.params.title }); render() { const {url} = this.props.navigation.state.params; return (<Image style={{flex: 1}} source={{uri: url}}/>) } }

navigationOptions akan secara otomatis dipanggil oleh React-Navigation.

Sekarang mari kita pindah ke App.js

Catatan: Ada banyak jenis navigasi di React-Navigation. Hari ini, kita akan fokus pada StackNavigation . Silakan merujuk ke situs web resmi untuk info detail.

 import React from 'react'; import {createStackNavigator} from "react-navigation"; import PictureList from "./components/PictureList"; import PicturePreview from "./components/PicturePreview"; export default class App extends React.Component { render() { return ( <Router/> ); } } //Customize the header_ const NavigationOptions = { headerTintColor: '#fff', headerStyle: { backgroundColor: '#f4511e', } }; //Create the router. const Router = createStackNavigator({ //Name the screen 'PictureList': { //Link the Component screen: PictureList, //Additional navigation options navigationOptions: { title: '/r/pics Browser', ...NavigationOptions } }, 'PicturePreview': { screen: PicturePreview, navigationOptions: NavigationOptions } }, { //Root initialRouterName: 'PictureList' } );

Seperti yang Anda lihat, yang perlu kita lakukan hanyalah membuat perute navigasi dan membuat aplikasi merendernya. Jika semuanya berjalan dengan baik, kami akan memiliki aplikasi browser Reddit /r/pics yang berfungsi.

Android:

Aplikasi penjelajahan terakhir di Android

iOS:

Aplikasi penjelajahan terakhir di iOS

React Native Luar Biasa!

Sejak saya memulai pemrograman, saya memiliki pengalaman pengembangan seluler murni. Tapi sekarang saya bisa membuat kode untuk hampir semua hal dengan React: mobile, desktop, dan web.

Jika Anda memutuskan untuk mulai mengembangkan aplikasi luar biasa berikutnya menggunakan React Native, Anda akan menemukan bahwa aplikasi tersebut memiliki kebiasaan dan beberapa bug di sana-sini, tetapi React Native sangat fungsional dan ideal untuk sebagian besar proyek.

Terkait: Membangun Pemindai QR: Tutorial Kamera Asli React