Başlarken...

Bu yazı, web developer'lerin React Native ile mobil uygulama geliştirmeye başlamasına destek amacıyla oluşturuldu. Mümkün olduğunca basit bir dille, hızlı bir başlangıç yapmanızı sağlamaya çalışacağım. Bi'şeyler ortaya koyduktan sonra detayları öğrenmek daha kolay ve motive edici olacaktır.

Kurulum

Kurulum aşamasını burada yazmıyorum. Bunun için çok güzel bir YouTube videosu, React Native Geliştirme Ortamının Kurulumu | Windows başlığında konuyu anlatıyor.

Merhaba Dünya

Uygulama Dosyalarının Hazırlanması

  1. Masaüstünde uygulamalarımızı koyacağımız bir Uygulamalarım klasörü oluşturalım.
  2. Uygulamalarım klasörünü açalım ve içinde boş bir yere Shift tuşu basılıyken sağ tıklayalım ve menüden Powershell penceresini buradan açın diyelim.
  3. npx react-native init ders1 komutunu vererek ders1 klasörü oluşmasını ve içine de react native için gereken dosyaların download edilmesini sağlayalım. İnternet hızına bağlı olarak birkaç dakika sürebilir. Kurulum bitip de Powershell kontrolü yeniden bize verdiğinde Powershell'i kapatabiliriz.
  4. Başlamak için dosyalarımız hazır. ders1 klasörüne girelim ve Visual Studio Code'yi burada açalım.

İlk Uygulamayı Çalıştırmak

  1. Öncelikle Android işletim sistemli cihazımızı USB ile bilgisayara bağlayalım.
  2. Visual Studio Code içinde terminali Ctrl+" tuşlarıyla açalım.
  3. Terminalde kök klasörümüzdeyken npx react-native run-android veya yarn android dediğimizde, kurulumda örnek olarak gelen uygulama başlatılır. İlk başlatmada verilerin derlenip toparlanıp elini yüzünü yıkayıp cihaza yüklenip açılması uzun sürer.

"Merhaba Dünya" Yazan Bileşen

  1. Uygulama, kök klasördeki index.js dosyasındaki AppRegistry.registerComponent(appName, () => App); ile çalışıyor. Burada App, kök klasördeki App.js dosyasından import edilen App bileşenidir. Bunu görün istedim. Bizim bu index.js dosyasında bir işimiz olmayacak.
  2. App.js dosyasını açalışm. Kafa karıştırmasın diye içinde ne var ne yoksa silelim. Şu anda index.js dosyası bizden App bileşeni export etmemizi bekliyor.
  3. Tüm uygulamayı kapsayacak ve index.js'e gönderilecek en parent bileşenimiz olan App bileşenimizi oluşturalım: function App() { }. Evet bu kadar. Bileşenleri sıradan js fonksiyonları olarak oluşturabiliyoruz.
  4. Bu bileşeni oluşturduk ama export etmedik. Bir alt satırda export edebiliriz: export default App;. Böylece index.js dosyası bileşenimizi yakalayabilir.
  5. Bileşenimiz bir bileşen return etmeli ki çalıştırıldığında ekrana bi'şeyler basılsın. Her bileşen ille de başka bir bileşen return eder. Biz ekrana bir "Merhaba Dünya" yazarak başlayacağız. Eğer ekrana bi'şeyler yazdırmak istiyorsak direkt yazamıyoruz. Yazıyı mutlaka <span> tag'ına benzer bir bileşen olan <Text> bileşenine sarmamız gerekiyor. Aksi halde, Text strings must be rendered within a <Text> component. diye hata alırız.
    function App() { return <Text>Merhaba Dünya</Text> }
    
    export default App;
    
    Gördüğünüz gibi App bileşenimiz, tüm uygulamayı içinde barındıran bir bileşen haline gelmeye başladı. Tabi şu an tüm uygulama tek bir <Text> bileşeninden ibaret ama olsun.
  6. Elbette biz şu an sadece pure javascript yazdık ve bu dosyanın React Native'den haberi yok. Bu yüzden react adlı kütüphaneyi import etmemiz gerekiyor. Ayrıca sayfamızda <Text> bileşenini kullandığımız için bu bileşeni de sayfamıza react bileşenlerini barındıran react-native kütüphanesinden çağırmamız gerekir.
    import React from 'react';
    import { Text } from 'react-native';
    
    function App() { return <Text>Merhaba Dünya</Text> }
    
    export default App;
    
  7. Artık tamam. Bu 4 satır, Merhaba Dünya uygulamamızı çalıştırmamıza yeter. Şimdi terminalden yarn android veya npx react-native run-android diyebiliriz. Kodumuz development modunda derlenip cihaza yüklenecek.

Birkaç ufak teknik detay...

Uygulamayı çalıştırdığınızda yeni bir konsol ekranı açılıyor. Bu ekran sizin uygulamanızla bağlantınız. Uygulamanızı geliştirirken açık kalmalı. Bazen yaptığınız değişiklikler uygulamaya aktarılamayabiliyor. Bu durumlarda bu ekrana gelip R tuşuna bastığınızda uygulamanız yeniden derlenip cihaza gönderilir. Bir de geliştirici menüsü var. Başlarda pek işimiz olmayacak olsa da söyleyelim. D butonu da bu menüyü açıyor.

Siz eğer böyle ayrı bir konsol ekranı olmasını istemiyorsanız, yönetimi Visual Studio Code'nin terminalinden yönetmek istiyorsanız uygulama açıldıktan sonra bu pencereyi kapatıp bağlantıyı koparın. Sonra kendi terminalinize gelip yarn start deyin. Sizin terminalinizden uygulamaya bağlantı kurulacaktır. Kapattığınız konsol ekranında yapabildiklerinizi artık kendi terminalinizden yapabilirsiniz.

Test Etmek için Uygulamanın APK'sını Oluşturmak

Detaylı bilgi için sabiha-durmaz.medium.com adresine bakabilirsiniz.

Uygulamanızı development modunda çalıştırırken arka planda birçok denetim gerçekleşiyor. Bu nedenle uygulamanıza verdiğiniz komutlar biraz geç işlenebiliyor. Peki uygulamayı production aşamasına aldığınızda da böyle mi olacak? Bazen bunu test etmek isteyebiliriz. Her zaman yapacağımız bi'şey değil ama gerçek bir APK oluşturmayı baştan öğrenmiş olalım. İleride lazım olunca buraya döner bakarız.

  1. Önce terminalden android klasörüne gidelim: cd android
  2. gradlew app:assembleRelease komutunu verelim.
  3. APK'mız oluştu. Dosyayı bulmak için masaüstünden Uygulamalarım/ders1/android/app/build/outputs/apk/release içinde gidebilir ve APK'yı telefonumuza atıp kurabiliriz. Tabi Android'e göre şu an kaynağı belirsiz, haliyle güvenilir olmayan bir uygulamayı telefona yüklemeye çalışıyoruz. Bu nedenle telefonun Developer Mode'de olması gerekiyor. Benim telefonum uzun süredir bu modda olduğu için bu modun nasıl etkinleştirildiğini hatırlamıyorum ama telefon sizi yönlendirecektir diye umuyorum.

Birkaç Bileşenden Oluşan ve Stillendirilmiş Bir Bileşen Yapalım

Öncelikle terminalde ders1 dizini içinde olduğumuzdan emin olalım ve yarn android diyerek uygulamamızı cihaza gönderelim. Belirtmek gerekir mi bilmem ama eğer terminaliniz halen ders1/android klasöründeyse cd.. diyerek bir üst klasör olan ders1 klasörüne dönebilirsiniz.

Bu başlık altında App bileşenine birkaç bileşen daha ekleyeceğiz ve biraz stil vereceğiz.

Öncelikle şunu bilmeniz gerekiyor: bir bileşen her zaman başka bir bileşen return eder. Bunun altını çizerek yazdım. return ettiğiniz bileşenlerin hepsi, kapsayıcı tek bir bileşen içinde bulunmalıdır.

Aşağıdaki örnekte, <div> etiketine benzetebileceğimiz, kafamıza göre her yerde kullanabileceğimiz ve en çok kullanacağımız bileşen olan <View> bileşenini kapsayıcı olarak kullanalım:

import React from 'react';
import { Text , View } from 'react-native';

function App() { 
    return (
    <View>
        <Text>Merhaba Dünya</Text>
        <Text>N'aptın? Nasıl gidiyor?</Text>
    </View>
)
}

export default App;

return ifadesinden sonra düzgün bir görünüm için parantez kullandık. 2 adet <Text> bileşeni return etmek için bunları bir <View> ile kapsadık ve böylece tek bir bileşen return etmiş olduk. Tabi View bileşenini import etmeyi de unutmadık. Uygulama çalıştığında sayfanın üst sol tarafında yazılarımız alt alta görünüyor olmalı.

Bunları sayfanın ortasına getirelim. Bileşenlere stil vermek için style attribute'sini/property'sini kullanıyoruz. Kullanalım o zaman:

import React from 'react';
import { Text, View } from 'react-native';

function App() { 
    return (
        <View style={{ flex:1, alignItems:'center', justifyContent:'center' }} >
            <Text style={{ textAlign:'center', padding:5, color:'#e03' }} >Merhaba Dünya</Text>
            <Text style={{ textAlign:'center', padding:5, color:'#06e' }} >N'aptın? Nasıl gidiyor?</Text>
        </View>
    )
}

export default App;

Javascript içine html/xml kodlarına benzer kodları direkt yazmamızı sağlayan şey React'ın JSX denen bir özelliği. Yukarıdaki tag'ları JS fonksiyonları yardımıyla da oluşturabilirdik ama JSX ile oluşturmak daha kolay olduğu için bu şekilde kullanıyoruz. Başlangıçta bir web developer'e JS içinde bu şekilde bir kullanım garip gelebilir ama zamanla alışıyorsunuz.

Yazdığımız şey tamamen Javascript olduğu için JSX kodu içine rahatlıkla JS kodu girebiliriz. Bunu yapacaksak { } kullanmamız gerekiyor. style attribute'si içine JS objesi gönderdiğimiz için önce { } ile JS kodu vereceğimizi söyledik. Sonra da bunun içine object'imizi gönderdik.

Peki bu object'leri doğrudan style attribute'sine/property'sine yazmak zorunda mıyız? Tabii ki hayır. CSS'teki class mantığına benzer şekilde stilleri dışarı da aktarabiliriz.

import React from 'react';
import { Text, View } from 'react-native';

function App() { 
    var styles = {
    container: { flex:1, alignItems:'center', justifyContent:'center' },
    text: { textAlign:'center', padding:5 },
    title: { color:'#e03', fontSize:20 },
    content: { color:'#06e', fontSize:13 }
}
    return (
        <View style={styles.container} >
            <Text style={[styles.text, styles.title]} >Merhaba Dünya</Text>
            <Text style={[styles.text, styles.content]} >N'aptın? Nasıl gidiyor?</Text>
        </View>
    )
}

export default App;

İnceleyecek olursak, App sayfamızda stillerimizi tanımladık ve JSX içinde de bunları kullandık.

Kapsayıcı <View> bileşenimize styles.container ile stilini CSS'te class verir gibi verdik.

<Text> bileşenlerimize 2 class birden verdik. Gördüğünüz gibi style attribute'sine array kullanarak birkaç class da gönderebiliyoruz.

Kullandığım dil oldukça yanlış. Web developer olarak kafanızda rahat ilişkilendirin diye "class", "attribute" gibi kelimeler kullanıyorum. Ama aslında burada ne attribute alan html tag'ları var ne de class tanımlanmış CSS kodları... Aslında attribute dediğim şey bir fonksiyona gönderilen parametredir. class dediğim şey de sıradan bir js object'tir. İleride dilimizi yavaş yavaş değişireceğiz.

Bu stiller şu an yalnızca App bileşeninde kullanılabilir. Çünkü kodları bileşenin içine yazdık. Normalde böyle yapılamz. Normalde, react-native kütüphanesi içindeki StyleSheet kullanılır.

import React from 'react';
import { Text, View , StyleSheet } from 'react-native';

function App() {
    return (
        <View style={styles.container}>
            <Text style={[styles.text, styles.title]}>Merhaba Dünya</Text>
            <Text style={[styles.text, styles.content]}>N'aptın? Nasıl gidiyor?</Text>
        </View>
    )
}

var styles = StyleSheet.create({
    container: { flex:1, alignItems:'center', justifyContent:'center' },
    text: { textAlign:'center', padding:5 },
    title: { color:'#e03', fontSize:20 },
    content: { color:'#06e', fontSize:13 }
})

export default App;

Böylelikle stilleri dışarı aktardık. İstersek bu sayfadaki birkaç bileşende birden aynı stilleri kullanabiliriz. Daha global olsun, başka sayfalardan da ulaşılabilsin istersek de bu stil kodlarını bakşka bir dosyaya aktarıp export edebilir ve istediğimiz sayfaya da import edebiliriz.

İyi ama biz neden StyleSheet kullandık ki? Bu stilleri direkt object olarak da kullanabiliyoruz. StyleSheet kullanmak bize ne kazandırıyor? Bunu direkt kodun GitHub kaynağından anladığım kadarıyla StyleSheet, kod okunabilirliğini artırıyor (doğru), kodun daha performanslı çalışmasını sağlıyor ve hatalı bir yazım varsa derlenirken hatayı StyleSheet'ten alıyoruz. Ayrıca editörlerin kod tamamlama özelliği de StyleSheet'i kullanırken bize önerilerle bulunabiliyor. Kısacası stiller bu şekilde kullanılmalı. :)

EcmaScript Kullanarak Kodlamak

Şu ana kadarki örneklerimizde hep eski yöntemle kodlama yaptık. function, var şeklinde ifadeler kullandık. Oysaki import ve export yeni Javascript'in özellikleri. Normalde tüm kodda yeni tarzda Javascript kullanmalıyız çünkü her yerde böyle kullanılıyor. Kodlarımızı düzenleyelim:

import React from 'react';
import { Text, View, StyleSheet } from 'react-native';

const App = () => {
    return (
        <View style={styles.container}>
            <Text style={[styles.text, styles.title]}>Merhaba Dünya</Text>
            <Text style={[styles.text, styles.content]}>N'aptın? Nasıl gidiyor?</Text>
        </View>
    )
}

const styles = StyleSheet.create({
    container: { flex:1, alignItems:'center', justifyContent:'center' },
    text: { textAlign:'center', padding:5 },
    title: { color:'#e03', fontSize:20 },
    content: { color:'#06e', fontSize:13 }
})

export default App;

Evet, çok da bi'şey değişmedi. Pek de "daha kısa, daha kolay" bir yazım şekli de olmadı. Ama ES6'nın güzellikleri ilerleyen zamanda karşımıza çıkacak. Alışın. Zaten alışkınsanız ne âlâ...

State Denen Mevzu

React Native uygulaması geliştirirken aslında bir server-side geliştirme yaptığınızı düşünebilirsiniz.

Web tarafında işler nasıl yürür? Bildiğiniz gibi; client, bir url istediğini söyler. Server de talebi alıp ilgili dosyayı bulur. Türlü işlemlerden geçirilmiş bir html string'i üretip bunu client'e gönderir. Şimdi client tarafında bu html üzerinde değişiklik yapılabilir ama bunlar server'in umrunda olmaz. Yapılan değişikliklerin server'e iletilmesi gerekir. Server, değişiklikleri alıp sayfayı yeniden oluşturur/render eder ve yeni bir html string'i oluşturup client'e gönderir.

React Native tarafında da böyledir. Aslında localhost'ta çalışan bir uygulamamız var gibi düşünebiliriz. Bir değişiklik varsa, bazı fonksiyonlar yardımıyla bunu sunucuya iletip sayfayı yeniden oluşturmasını isteriz. Hemen bir örnek verelim:

import React , {useState} from 'react';
import { Text, View, StyleSheet , Button } from 'react-native';

const App = () => {

    const [myValue, setMyValue] = useState(10);

    return (
        <View style={styles.container}>
            <Text style={[styles.text, styles.title]}>Merhaba Dünya</Text>
            <Text style={[styles.text, styles.content]}> {myValue} </Text>
            <Button title="myValue değerine 1 ekle" style={styles.button} onPress={ () => setMyValue( myValue + 1 ) } />
        </View>
    )
}

const styles = StyleSheet.create({
    container: { flex:1, alignItems:'center', justifyContent:'center' },
    text: { textAlign:'center', padding:5 },
    title: { color:'#e03', fontSize:20 },
    content: { color:'#06e', fontSize:13 },
    button: { marginTop:5 }
})

export default App;

Bir sürü yeni kod araya girdi. Yeni kodlarımızı inceleyelim:

Bir değişiklik yapmak istediğimizde değişkenin değerini doğrudan değiştirmiyoruz. Bunun yerine useState() fonksiyonuyla elde ettiğimiz fonksiyonu kullanmamız gerekiyor. Bu şekilde, hangi bileşenin içindeysek o bileşenin yeniden render edilmesini sağlıyoruz. Evet, butona her bastığımızda App sayfamız, içindeki tüm bileşenlerle birlikte yeniden render ediliyor ve render hazır olduğunda bileşen yeniden çiziliyor. Tabi bu işlem çok hızlı olduğu için fark edemiyoruz.

useState kullanımına örnek: YouTube: Ali Özkan: React Hooks - useState Kullanımı

Web API'dan Veri Çekmek

Buralara biraz hızlı geldik ama şunu yapamamamız için bir neden yok. Bir web API'dan veri çekelim ve bir <Text> bileşeni içine bunu yazalım.

Gereksinimler

axios kütüphanesinin kurulumu

Terminalinizde şu kodu vermeniz yeterli: yarn add axios

Sayfamıza import etmek için de birazdan şu kodu kullanacağız: import axios from 'axios';

Web API'dan Veri Çekelim

import React, {useState , useEffect } from 'react';
import { Text, View, StyleSheet } from 'react-native';
import axios from 'axios';

const App = () => {

    const [myValue, setMyValue] = useState( "Sonuç bekleniyor..." );

    useEffect(
    () => { // function functionName() { ile aynı sonucu üreten satır 
        axios
            .get('https://jsonplaceholder.typicode.com/todos/1') // Buraya get isteği yap
            .then( (response) => { setMyValue(response.data.title); } ) // İstek sonuçlandığında myValue değerine response ile gelen değeri ata
            .catch( (error) => { console.log(error); }) // Hata olursa console ekranına yaz
    },
    [] // boş array
);

    return (
        <View style={styles.container}>
            <Text style={[styles.text, styles.title]}>Merhaba Dünya</Text>
            <Text style={[styles.text, styles.content]}>{myValue}</Text>
        </View>
    )
}

const styles = StyleSheet.create({
    container: { flex:1, alignItems:'center', justifyContent:'center' },
    text: { textAlign:'center', padding:5 },
    title: { color:'#e03', fontSize:20 },
    content: { color:'#06e', fontSize:13 }
})

export default App;

Ne oldu? Sayfa yüklendiğinde ilk etapta ikinci <Text> elementinde myValue değerinin ilk değeri olarak belirlenen "Sonuç bekleniyor..." string'i görünüyordu. Bu sırada sayfa ilk yüklendiğinde useEffect() fonksiyonunun içindeki fonksiyon çalıştı ve get isteği uzak sunucuya gönderildi. Kısa bir süre sonra get isteğinden yanıt döndü ve myValue değeri setMyValue() fonksiyonu ile güncellendi ve sayfa yeniden render edildi.

Akıllardaki soru: peki sayfa yeniden yüklendiyse neden useEffect() fonksiyonu yeniden çalışmadı (ve haliyle yeniden get isteği yapılmadı)? Bunu sağlayan şey, useEffect() fonksiyonuna verdiğimiz ikinci parametre olan boş array. Eğer useEffect() fonksiyonuna ikinci parametreyi hiç vermezsek, sayfa her render edildiğinde bu fonkisyon çalışır. İkinci parametre olarak boş bir array verirsek sadece sayfa ilk yüklendiğinde çalışır.

Peki ama ikinci parametrenin tipi neden array? Bu array'a ne değerler verilebiliyor? Bu array'a state değişkenlerinin adlarını verebiliyoruz. State değişkeni derken myValue değişkeninden bahsediyorum. Başka state değişkenlerimiz varsa onları da diziye eleman olarak verebiliriz. Bu da useEffect() fonksiyonuna şunu söyler: Bu dizinin içindeki state'ler değişmişse ilk parametrendeki fonskiyonu çalıştır! Yani diziye myValue değişkenini yazsaydık, sadece myValue değeri değiştiği zaman useEffect() fonksiyonuna ilk parametrede verdiğimiz fonksiyon çalışırdı. Bizim örneğimizde zaten başka bir state değişkeni olmadığı için bu diziye değer vermekle vermemek aynı şey.

useEffect()'le ilgili son bir not olarak, ikinci parametre olsun olmasın sayfa ilk kez yüklendiğinde bu fonksiyon mutlaka çalışır. Sayfa bir state değişimi yüzünden yeniden render edilmişse de, sadece diziye verilen state'lerden biri değişmişse fonksiyon çalışır. Haliyle diziye hiç eleman vermiyorsak, bu şekilde bir render olayında fonksiyon yeniden çalışmamış oluyor.

Tabii ki bize API'lardan her zaman böyle tek satırlık veriler gelmeyecek. Gelen çok satırlı verileri belli bir düzende loop etmek gerekecek. Ama nihayetinde veri çekme mantığını görmüş olduk. Listeleme işlemlerine geçtiğimizde bu işlemlerin gayet kolay olduğunu göreceksiniz.

useEffect kullanımına örnek: YouTube: Ali Özkan: React Hooks - useEffect Kullanımı
axios kullanımına örnek: YouTube: React Dersleri: React içinde fetch() ve axios ile API'dan veri almak

FlatList Kullanımı

Bu bileşen çok kullanılan bir loop bileşenidir. Belli bir veriyi alıp döngüye sokar ve bir bileşeni döngü dönerince tekrarlar. Hatta araya seperatör mantığında başka bileşenler de sokabilir.

App fonksiyonumuzun içini FlatList örneğine göre düzenleyelim:

import React, {useState, useEffect} from 'react';
import {Text, View, StyleSheet , FlatList } from 'react-native';
import axios from 'axios';

const App = () => {

    const [myValue, setMyValue] = useState( [] );

    useEffect(
    () => { // function functionName() { ile aynı sonucu üreten satır 
        axios
            .get( 'https://jsonplaceholder.typicode.com/todos' ) // Buraya get isteği yapıp çok satırlı bir veri alacağız
            .then( (response) => { setMyValue( response.data ); } ) // İstek sonuçlandığında dönen diziyi myValue değişkenine aktar
            .catch( (error) => { console.log(error); })
        },
        []
    );

    return (
        <View style={styles.container}>
            <FlatList style={styles.list}
    data={myValue}
    renderItem={ ({item}) => <RowItem item={item} /> }
    ItemSeparatorComponent={ () => (<View style={{height:1, flex:1, backgroundColor:'#000'}}></View>) }
/>
        </View>
    )
}

const RowItem = ({item}) => {
    return (
        <View style={styles.row}>
            <View style={styles.row_title}>
                <Text style={styles.row_title_text}>Title: {item.title}</Text>
            </View>
            <View style={styles.row_ids}>
                <Text style={styles.row_ids_text}>User Id: {item.userId}</Text>
                <Text style={styles.row_ids_text}>Id: {item.id}</Text>
            </View>
        </View>
    )
}

const styles = StyleSheet.create({
    container: { flex:1, alignItems:'center', justifyContent:'center' },
    list: { flex:1 },
row: {  },
row_title: { backgroundColor:'#eee', padding:5, borderBottomWidth:1, borderBottomColor:'#ddd' },
row_title_text: { fontSize:16, fontWeight:'bold', textAlign:'center', color:'#f02'},
row_ids: { flexDirection:'row', justifyContent:'center'},
row_ids_text: { padding:10},
text: { textAlign: 'center', padding: 5 },
title: { color: '#e03', fontSize: 20 },
});

export default App;

Bu örnekte dikkatinizi <RowItem /> bileşeni çekmiştir. Kendi bileşenimizi oluşturduk ve tıpkı <View> gibi, <Text> gibi kullandık. Gördüğünüz gibi item adlı bir attribute/property alıyor ve kendi fonksiyonu içinde de bunu parametre olarak yakalıyor.

Aslında <FlatList> bileşenini de çok anlatmaya gerek yok. data attribute'sine elemanları tek tek dönülecek diziyi verdik. renderItem için de bir bileşen/component gösterdik. Bu ikisi zorunlu attribute'lerdi. Keyfi olarak da seperatör olarak kullanacağım bir <View> bileşeni verdim. Sonuç ortada...

<FlatList /> bileşeninin bir güzelliği de kendi scroll özelliğine sahip olması. Normalde ekrandan taşan bir öğe (mesela içeriği çok uzun bir <Text> bileşeni) varsa taşar gider ve web'dekinden farklı olarak otomatik bir scrollbar oluşmaz. CSS de yok ki overflow-y:scroll deyip scrollbar çıkaralım... Bu, native programlamada böyle ne yazık ki... Çözüm? Eğer scroll edilebilir bir içeriğimiz varsa bu içeriği scroll edilebilir bir bileşene sarmalıyız. Bu örneğimizde <FlatList /> bize bunu sağladı. Ama tasarımımız taşacaksa <ScrollView> adlı bir bileşen de react-native kütüphanesinde mevcut. Kullanımı <View> ile aynı.

<FlatList /> bileşeninin bir başka güzelliği de içeriğe lazyload uygulaması. O an ekranda görünmeyen içerikleri ekranda göstermiyor ve bu şekilde performans kazanımı sağlıyor. Çok hızlı şekilde ekranı kaydırırsanız hızınıza yetişemediği yerde bu olayı fark edebilirsiniz.