Android Geliştirme için React Native'e dalın

Yayınlanan: 2022-03-11

Birkaç yıl önce bir iş arkadaşım bana React Native'den bahsetti. çok şüpheciydim. Bunun gerçek hayatta asla çalışmayacak başka bir platformlar arası çerçeve olduğunu savundum - ne kadar yanlış olduğumu çok az biliyordum.

Yıllar geçti ve React Native becerileri çok talep görmeye başladı. Yeni bir şey öğreneli uzun zaman olduğu için, neden denemeyeyim diye düşündüm. Bugün, büyük React Native savunucusuyum.

Eksileri:

  • Artık Android Studio'yu kullanamazsınız
  • React Native her uygulama veya özellik için kullanılamaz
  • React Native yeni bir çerçevedir ve güncellemelerin mevcut kod tabanınız üzerinde olumsuz bir etkisi olabilir.
  • JavaScript kesinlikle yazılan bir dil değil
  • React Native'in çalışması için bir JavaScript motoru gerekir, bu da onu daha az performanslı hale getirebilir

Artıları:

  • Öğrenmesi kolay
  • Platform deneyimlerini eşleştirmek için yalnızca küçük ince ayarlar gerektiren, Android ve iOS uygulamaları arasında paylaşılan bir kod tabanı
  • Canlı ve sıcak yeniden yükleme, yani artık sonsuz inşa süresi yok
  • Her iki platform için yerel bileşenler
  • Sürekli iyileştirme
  • Aktif olarak büyüyen topluluk
  • Çok sayıda kütüphane
  • Expo, iOS için geliştirme yapmak için bir Mac'e sahip olma ihtiyacını ortadan kaldırıyor
  • İş gücü kaynaklarında azalma—hala bazı Android/iOS yerel geliştirmeye ihtiyacınız olsa da, bu nadir olacaktır.

Daha da uzatabilirim ama burada duralım ve bu blog yazısının konusuna geçelim. Bu yazıda, dört adet React Native destekli Android uygulaması oluşturacağım:

  1. Sayacı artırmak ve azaltmak için düğmelere sahip temel bir sayaç
  2. r/pics alt dizininde arama yapmak için bir uygulama
  3. Genel bir giriş sayfası
  4. r/pics alt dizinine göz atmak için bir uygulama

IDE

Yukarıda bahsettiğim gibi, Android Studio'yu React Native geliştirme için kullanmamızın bir yolu yok. Bir yedek oyuncuya ihtiyacımız var. React Native, muhtemelen mevcut herhangi bir modern metin düzenleyicide (Atom, VS Code, Sublime Text, Brackets, vb.) geliştirilebilir, ancak Android Studio deneyimiyle geldiğimiz için favorim, aynı şirket tarafından oluşturulan WebStorm. WebStorm ücretli bir uygulama olmasına rağmen (yıllık 129$) Erken Erişim sürümünü kurabilirsiniz. WebStorm'un EAP yapısı ücretsizdir ve oldukça kararlıdır. Tamamen ücretsiz bir editör tercih ediyorsanız, VS Code'a gidin. Microsoft, bunun için harika React Native eklentisi bile geliştirdi ve çok iyi çalışıyor.

Yeni Proje Oluşturma

Önkoşullar: Bilgisayarınızda yüklü Android SDK, Node ve React Native.

Yeni React Native projesi oluşturmanın iki yolu vardır.

  1. Geleneksel yol. WebStorm GUI ile veya terminal komutuyla: react-native init AwesomeToptalProject
  2. "React Native App Oluşturun" daha kolay yolu. create-react-native-app AwesomeToptalProject

create-react-native-app kullanıyorsanız, oluşturulan proje expo ile önyüklenir. Ayrıntılara girmeyeceğim, ancak temelde, bu, uygulamayı iOS'ta çalıştırmak için Xcode'un kurulu olmasına gerek olmadığı anlamına gelir. Ayrıca, expo.io'nun işlevselliği ve diğer bazı özellikleri aracılığıyla istemcinin her zaman güncel olmasını sağlamak daha kolaydır. Ancak yerel kod ekleyemezsiniz. Bu nedenle, belirli bir özellik geliştiriyorsanız, bir uygulamayı fuardan çıkarmanız ve bunun yerine normal bir React Native projesi kullanmanız gerekebilir.

İlk yöntemi kullanacağım.

Projeyi çalıştıralım. İlk önce bir emülatör açın veya cihazı bağlayın. Projeyi WebStorm GUI ile oluşturduysanız, tek yapmanız gereken bir konfigürasyon seçmektir. WebStorm'un sağ üst köşesinde, Çalıştır düğmesinin solundaki açılır menüyü tıklayın, Android'i seçin ve Çalıştır veya Hata Ayıkla'yı tıklayın. Projeyi Terminal ile oluşturduysanız, yeni bir React Native yapılandırması ekleyebilir veya Terminal kullanarak çalıştırabilirsiniz:

 cd AwesomeToptalProject react-native run-android

Her şey yolunda giderse, aşağıdaki ekranla karşılaşacaksınız:

Oluşturulan düzen

Yapı ve Temel Kurulum

Projedeki dikkate değer öğeler şunlardır:

  • android - React Native desteği ile önceden yapılandırılmış Android Studio projesi.
  • ios - React Native desteği ile önceden yapılandırılmış Xcode projesi.
  • node_modules - React Native çerçevesini ve diğer Javascript kitaplıklarını içeren bir klasör.
  • index.js - Uygulamamız için bir giriş noktası.
  • App.js - İlk bileşen yüklendi.

Projenin kök dizininde bir “src” klasörü oluşturalım ve App.js'yi oraya taşıyalım. Yeni App.js konumuyla eşleşmesi için index.js içe aktarmalarını güncellemeniz gerekecek.

 import App from './src/App';

App.js içindeki her şeyi silin ve şu kodu yapıştırın:

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

Yapıştırdığımız kod oldukça basit. render() yöntemini geçersiz kılan ve Text bileşenini döndüren bir App sınıfı ( React.Component alt öğesi) oluşturduk. React.Component , JSX kullanarak UI oluşturmak için temel sınıftır. export default değiştiricisi, sınıfı public yapar.

Artık düzenimizi tasarlamaya başlamaya hazırız.

Flexbox ile Düzen

Flexbox , LinearLayout benzer, ancak Flexbox , LinearLayout yeteneklerinin çok ötesine geçer.

JSX'in bu pasajı:

 <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>

Bu düzeni işler:

Oluşturulan düzen


Bu XML iken:

 <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>

Bunu oluşturur:

Oluşturulan düzen

JSX kodu tanıdık geliyor, ha?! JSX ve Android XML'de benzer görünen mizanpajlar için bir "sözlük" (veya bir hile sayfası) oluşturalım.

Lütfen işlevlerin mutlaka eşit olmadığını unutmayın. React Native'deki düzen sistemi fikrini kavramak için React Native'e yeni başlayanlara yardım etmeye çalışıyorum. Ayrıntılı bilgi için lütfen resmi kılavuza bakın.

Bu JSX özelliğini düşünün:

 flex: 1

Buna eşdeğerdir:

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

JSX'in bu pasajı:

 <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>

Ve bu XML:

 <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>

Her ikisi de bu çıktıyı üretir:

Oluşturulan düzen


Benzer şekilde, bu JSX:

 <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>

Ve bu XML:

 <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>

Bunu oluştur:

Oluşturulan düzen


Kap içinde doğru konumu elde etmek için en yaygın olarak flexDirection , alignItems ve justifyContent özelliklerinin bir kombinasyonunu kullanacağız.

Bu JSX:

 <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>

Ve bu XML:

 <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>

Bu düzeni üretecek:

Oluşturulan düzen


Bu JSX:

 <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>

Ve bu XML

 <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>

Bu düzeni üretecek:

Oluşturulan düzen


Bu JSX:

 <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>

Ve bu XML:

 <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>

Bu düzeni üretecek:

Oluşturulan düzen


Bu JSX:

 <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>

ve bu XML:

 <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>

Bu düzeni üretecek:

Oluşturulan düzen


flexDirection: row', alignItems works on Y axis and justifyContent works on X axis. Everything is mirrored for flexDirection: column' works on X axis. Everything is mirrored for - justifyContent Y eksenini etkiler ve alignItems Y eksenini etkiler.

justifyContent: 'esnek başlangıç' yerçekimi="başlangıç|sol"
alignItems: 'esnek başlangıç' yerçekimi="başlangıç|sol"
justifyContent: 'esnek uç' yerçekimi="son|sağ"
alignItems: 'esnek uç' yerçekimi="son|sağ"

Kendin dene. justifyContent değerini space-around , space-between ve space-evenly evenly olarak ayarlayın.

Durum Yönetimi

Uygulama durumunu güncellemek için React'in state değişkenini kullanacaksınız. state güncellendiğinde, render() çağrılır.

Aşağıdaki kodu uygulamanıza kopyalayın:

 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}); } }
Son azalma uygulaması

AZALTMA ve ARTIRMA butonlarına tıklarsanız metnin sizin için otomatik olarak güncellendiğini göreceksiniz. textView.setText("Value " + number) açıkça kullanmaya gerek yoktur.

Durum işlevselliği birçok nedenden dolayı kullanışlıdır:

  • Değeri elde etme kolaylığı—belirli bir değişken için değeri nereden ve nasıl elde edeceğinizi her zaman bilirsiniz.
  • Veriler belirli widget'lara bağlı değildir.
  • Ortak değer değişikliğine bağlı birden fazla widget'a sahip olmak.

/r/pics için bir Arama Uygulaması Oluşturma

Artık temelleri kavradığımıza göre, biraz daha karmaşık bir şey oluşturalım: /r/pics için bir arama uygulaması. Reddit, basit bir JSON API uç noktası sağlar, bu nedenle doğru çalışması için kimlik doğrulaması almak üzere yan görevlere gitmemiz gerekmeyecektir.

React Native, yerleşik bir Fetch API sağlar. Çoğumuz muhtemelen Retrofit'e ve kullanım kolaylığına alıştığımız için, axios kullanacağız . Axios'u bir terminal komutuyla yükleyebilirsiniz.

yarn kullanarak (Tercih ettiğim yöntem):

yarn add axios

veya npm kullanarak:

npm install axios

İthalat:

 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

Sınıfı oluşturun:

 export default class App extends React.Component { }

Durumu başlatmak için. İhtiyacımız olacak:

  • yükleniyor - Bir ilerleme çubuğu göstermek için.
  • error - REST API isteği yapılırken bir hatanın oluşup oluşmadığını göstermek için.
  • imgUrl - Aranan resmin önizlemesini yapmak için.
  • metin - arama sorgusu.
 state = {text: '', loading: false, error: null, imgUrl: null};

JSX kodunu ekleyin. TextInput ve Image bileşenleriyle dikey bir yerleşimimiz var.

 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> ); }

Yeni şeyler:

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

İlk yöntem, TextWatcher bileşeniyle EditText benzer bir çalışma yapar. Dürüst olalım, React Native'de çok daha güzel.

İkinci yöntem, searchPicture() tetikledikten sonra klavyede ( et.OnEditorActionListener ) dönüş tuşuna basıldığında çağrılır.

'&&' operatörü, birincisi zaten yanlışsa ikinci bir bağımsız değişkeni kontrol etmediğinden, imgUrl boş veya tanımsız olmadığında Görüntü oluşturulur.

this.state.imgUrl neden yanlış olduğunu merak ediyor olabilirsiniz. JavaScript'te mantıksal operatörler kullanırken, '' (boş bir dize), 0 , false , null veya undefined dışında her şey doğrudur. Özel bir kontrole gerek yoktur.

 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}) }) }

İşte başlıyoruz. Uygulama şimdi beklendiği gibi çalışmalıdır. Bir arama dizisi girin ve geri dönüş tuşuna basın.

Son reddit arama uygulaması

Uygulamamız da ActivityIndicator ve hataları oluşturmaya hazır olduğundan, Image bileşeninden sonra biraz daha kod eklememiz gerekiyor:

 { //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> }

Render bileşenlerini ana render() yönteminin dışına da taşıyabilirsiniz:

 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> ); } }

Geriye sadece stiller kaldı. Bunları App sınıfının dışına koyun.

 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 } });

Artık, uygulama başlatıldığında yumuşak klavyeyi otomatik olarak açmak gibi biraz daha ince ayar ekleyebiliriz.

Lütfen TextInput otomatik olarak odaklamanın daha kolay bir yolu olduğunu unutmayın ( autoFocus={true} prop ), ancak bu örnek için onu kullanmayacağız.

Prop ile TextInput referans ekleyin:

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

Ve componentDidMount() yaşam döngüsü yöntemini şu şekilde geçersiz kılın:

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

Uygulamayı yeniden yükleyin ve klavye bizim için otomatik olarak açılır.

Bileşen Yaşam Döngüsü Yöntemleri

Zaten bir bileşen oluşturduk, ancak bir bileşenin ömrünü gözden geçirelim.

İşte React'in yaşam döngüsü akışı:

  • constructor() - Uygulama başlatıldığında yapıcı her zaman çağrılır
  • static _getDerivedStateFromProps_(props, state) - Oluşturmadan önce ve güncellemeden sonra çağrılır. Durumu güncellemek için nesneyi döndürür. Hiçbir şeyi güncellemek için null döndürün.
  • render() - Her React Component sınıfı için render gereklidir. Görünümü oluşturmak için kullanılır.
  • componentDidMount() - Bileşen işlendikten ve görünüm ağacına monte edildikten sonra çağrılır.
  • shouldComponentUpdate(nextProps, nextState) - Durum veya donanım değişikliğinden sonra çağrılır. Her durum güncellemesinden sonra dönüş varsayılan olarak true olur. true döndürürse render() ı çağırır.
  • getSnapshotBeforeUpdate(prevProps, prevState) - İşlenen çıktı işlenmeden hemen önce çağrılır.
  • componentDidUpdate(prevProps, prevState, snapshot) - Yeni güncelleme oluşturulduktan sonra çağrılır. İlk render() işleminden sonra çağrılmaz.
  • componentWillUnmount() - Bileşen sökülmeden ve yok edilmeden hemen önce çağrılır.

Bileşen yaşam döngüsü tablosu

Yeniden Kullanılabilir Bileşenler

Proje üzerinde çalışırken genellikle yeniden kullanılabilir bileşenler oluşturmamız gerekir. Bir bileşen oluşturmanın iki yolu vardır:

  1. React.Component genişleten bir sınıf oluşturma. Yaşam döngüsü yöntemlerine ihtiyacımız varsa bu yöntem kullanılmalıdır.
  2. Daha basit bir sözdizimi için Görünüm döndüren bir işlev yazarak.

Bileşen sınıflarını zaten oluşturduğumuz için bu örnek için bir fonksiyon oluşturalım.

<CardView> için bir analoga ihtiyacımız olduğunu varsayalım. ./src dizini altında bir “ortak” klasör oluşturun.

CardView.js oluşturun.

 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' } };

Yeni LoginForm kullanarak CardView :

 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' } }) } });

LoginForm sınıfını App sınıfına alın ve View ile sarın

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

Stillerdeki parametreleri değiştirirseniz, çok daha güzel görünen bir şey elde edebilirsiniz.

Nihai oluşturulan giriş formu uygulaması

Navigasyon

Farklı sahnelerde gezinme, uygulamaların çoğu için önemli bir kısımdır. Bir Reddit /r/pics tarayıcı uygulaması oluşturacağız.

React Native'de navigasyon oluşturmak oldukça kolaydır.

Önkoşullar

  • yarn veya npm ile react-navigation kurun
  • yarn veya axios ile npm

İki farklı bileşen oluşturarak başlayalım.

Not: Aşağıdaki kodun çoğu size zaten aşina olmalıdır. Bütün sınıfı yapıştıracağım.

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 Seçenekleri, React-Navigation tarafından otomatik olarak çağrılır.

Şimdi App.js'ye geçelim

Not: React-Navigation'da birçok navigasyon türü vardır. Bugün, StackNavigation odaklanacağız. Ayrıntılı bilgi için lütfen resmi web sitesine bakın.

 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' } );

Gördüğünüz gibi, tek yapmamız gereken bir navigasyon yönlendiricisi oluşturmak ve uygulamanın onu render etmesini sağlamak. Her şey yolunda giderse, işlevsel bir Reddit /r/pics tarayıcı uygulamamız olacak.

Android:

Android'de son tarama uygulaması

iOS:

iOS'ta son tarama uygulaması

React Native Harika!

Programlamaya başladığımdan beri tamamen mobil geliştirme deneyimlerim oldu. Ancak artık React: mobil, masaüstü ve web ile hemen hemen her şeyi kodlayabiliyorum.

Bir sonraki harika uygulamanızı React Native kullanarak geliştirmeye karar verirseniz, burada ve orada bazı tuhaflıkları ve bazı hataları olduğunu göreceksiniz, ancak React Native çok işlevsel ve çoğu proje için idealdir.

İlgili: Bir QR Tarayıcı Oluşturun: Bir React Yerel Kamera Eğitimi