Cara menggunakan REACT-NATIVE-ASYNC-STORAGE/ASYNC-STORAGE pada JavaScript

React Native Async Storage

An asynchronous, unencrypted, persistent, key-value storage system for React Native.

Supported platforms

  • iOS
  • Android
  • Web
  • MacOS
  • Windows

Getting Started

Head over to documentation to learn more.

Contribution

Pull requests are welcome. Please open an issue first to discuss what you would like to change.

See the CONTRIBUTING file for more information.

License

MIT.

Pada tutorial ini, kita akan membuat aplikasi pembaca berita dengan React Native. Dalam seri bagian kedua ini, saya akan berasumsi bahwa ini bukan aplikasi React Native pertamamu dan saya tidak akan menjelaskan secara detail tentang menyiapkan mesinmu dan menjalankan aplikasi di perangkat. Yang dikatakan, saya menjelaskan proses pengembangan yang sebenarnya secara rinci.

Table of Contents

  • 1. Pengaturan Proyek
  • Langkah 1: Membuat Aplikasi Baru
  • Langkah 2: Menginstal Dependensi
  • 2. Komponen Utama
  • Komponen NewsItem
  • Langkah 1: Mengimpor Komponen & Library
  • Langkah 2: Membuat komponen NewsItems
  • Langkah 3: Mengimplementasikan Fungsi render
  • Langkah 4: Mengimplementasikan Fungsi componentDidMount
  • Langkah 5: Mengimplementasikan Fungsi renderNews
  • Langkah 6: Mengimplementasikan Fungsi updateNewsItemsUI
  • Langkah 7: Memperbarui Local Storage
  • Langkah 8: Mengambil Item Berita
  • Langkah 9: Styling

Meskipun kita akan menerapkannya ke Android, kode yang digunakan dalam tutorial ini seharusnya juga bekerja pada iOS. Inilah hasil akhir tampilannya.

Kamu dapat menemukan kode sumber yang digunakan pada tutorial ini di GitHub.

Prasyarat

Jika kamu baru mengenal React Native dan belum menyiapkan mesinmu, pastikan untuk memeriksa panduan memulai dari dokumentasi React Native atau membaca tutorial pengantar Ashraff di Envato Tuts+. Jangan lupa untuk menginstal SDK Android jika kamu ingin mendeploynya ke Android atau menginstal Xcode dan SDK untuk iOS.

Setelah selesai, instal NodeJS dan tool command line React Native menggunakan npm.

npm install -g react-native-cli

1. Pengaturan Proyek

Kita sekarang siap untuk membuat proyek ini. Sebelum memulai, saya ingin memberikan gambaran singkat tentang bagaimana proyek digabungkan. Kita membuat dua komponen khusus:

  • NewsItems yang merender item berita
  • WebPage yang merender halaman web saat pengguna mengetuk item berita

Ini kemudian diimpor ke file titik masuk utama untuk Android [index.android.js] dan untuk iOS [index.ios.js]. Itu saja yang perlu kamu ketahui sekarang.

Langkah 1: Membuat Aplikasi Baru

Mulailah dengan menavigasi ke direktori kerjamu. Buka jendela terminal baru di dalam direktori itu dan jalankan perintah berikut:

react-native init HnReader

Ini membuat folder baru bernama HnReader dan berisi file yang dibutuhkan untuk membuat aplikasi.

React Native sudah hadir dengan beberapa komponen bawaan, namun ada juga yang khusus yang dibangun oleh pengembang lain. Anda bisa menemukannya di website react.parts. Tidak semua komponen bekerja di Android dan iOS sekalipun. Bahkan beberapa komponen bawaannya tidak lintas-platform. Itulah mengapa kamu harus berhati-hati saat memilih komponen karena mereka mungkin berbeda pada setiap platform atau mungkin tidak bekerja dengan benar di setiap platform.

Sebaiknya masuk ke laman masalah repositoru GitHub dari komponen yang kamu rencanakan untuk digunakan dan telusuri salah satu dukungan android atau dukungan ios untuk segera memeriksa apakah komponen bekerja di kedua platform.

Langkah 2: Menginstal Dependensi

Aplikasi yang akan kita bangun bergantung pada beberapa library pihak ketiga dan komponen React. Kamu bisa menginstalnya dengan membuka package.json di direktori root kerjamu. Tambahkan yang berikut ini ke package.json:

{
  "name": "HnReader",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "react-native start"
  },
  "dependencies": {
    "lodash": "^4.0.1",
    "moment": "^2.11.1",
    "react-native": "^0.18.1",
    "react-native-button": "^1.3.1",
    "react-native-gifted-spinner": "0.0.3"
  }
}

Selanjutnya, buka jendela terminal di direktori kerja dan jalankan npm install untuk menginstal dependensi yang ditentukan di package.json. Berikut adalah uraian singkat tentang apa yang masing-masing library lakukan pada proyek ini:

  • lodash digunakan untuk menyingkat string. Ini mungkin sedikit berlebihan, tapi satu baris kode yang harus kamu tulis berarti satu kewajiban yang lebih kecil.
  • moment digunakan untuk menentukan apakah item berita di local storagel sudah ada di sana untuk satu hari.
  • react-native adalah framework React Native. Ini terinstall secara default saat anda menjalankan react-native init tadi.
  • react-native-button adalah komponen react native yang digunakan untuk membuat tombol.
  • react-native-gifted-spinner digunakan sebagai indikator aktivitas saat membuat request jaringan.

2. Komponen Utama

Seperti yang saya sebutkan sebelumnya, titik masuk untuk semua proyek React Native adalah index.android.js dan index.ios.js. Itulah fokus pada bagian ini. Ganti isi file-file itu dengan yang berikut ini:

'use strict';
var React = require['react-native'];

var {
  AppRegistry,
  StyleSheet,
  Navigator
} = React;


var NewsItems = require['./components/news-items'];
var WebPage = require['./components/webpage'];

var ROUTES = {
  news_items: NewsItems,
  web_page: WebPage
};

var HnReader = React.createClass[{  

  renderScene: function[route, navigator] {

    var Component = ROUTES[route.name];
    return [
        
    ];
  },

  render: function[] {
    return [
       { return Navigator.SceneConfigs.FloatFromRight; }} />
    ];

  },


}];


var styles = StyleSheet.create[{
  container: {
    flex: 1
  }
}];

AppRegistry.registerComponent['HnReader', [] => HnReader];

Biarkan saya memecahnya. Pertama, kita aktifkan mode strict [ketat] dengan menggunakan direktif use script. Hal ini membuat parser melakukan lebih banyak pemeriksaan pada kodemu. Sebagai contoh, ini akan mengeluh jika kamu menginisialisasi variabel tanpa menambahkan kata kunci var.

'use strict';

Selanjutnya, kita mengimpor framework React Native. Ini memungkinkan kita membuat komponen khusus dan menambahkan styling ke aplikasi.

var React = require['react-native'];

Kita kemudian mengekstrak semua fungsi yang kita butuhkan dari objek React.

var {
  AppRegistry,
  StyleSheet,
  Navigator
} = React;

Jika kamu baru mengenal ES6 [ECMAScript 6], snippet di atas identik dengan:

var AppRegistry = React.AppRegistry;
var StyleSheet = React.StyleSheet;
var Navigator = React.Navigator;

Ini adalah sintaktis manis yang diperkenalkan di ES6 untuk membuat penugasan sifat objek ke variabel lebih mudah. Ini disebut destructuring assignment [penugasan destrukturisasi].

Berikut adalah uraian singkat tentang masing-masing properti yang telah kita ekstrak:

  • AppRegistry digunakan untuk mendaftarkan komponen utama aplikasi.
  • StyleSheet digunakan untuk mendeklarasikan style yang akan digunakan oleh komponen.
  • Navigator digunakan untuk beralih antar halaman aplikasi yang berbeda

Selanjutnya, kita mengimpor komponen khusus yang digunakan oleh aplikasi. Kita akan membuatnya nanti.

var NewsItems = require['./components/news-items'];
var WebPage = require['./components/webpage'];

Buat variabel ROUTES dan tetapkan sebuah objek menggunakan dua komponen di atas sebagai nilai untuk propertinya. Ini memungkinkan kita menampilkan komponen dengan mengacu pada masing-masing tombol yang telah kita definisikan.

var ROUTES = {
  news_items: NewsItems,
  web_page: WebPage
};

Buat komponen utama aplikasi dengan memanggil metode createClass dari objek React. Metode createClass menerima sebuah objek sebagai argumennya.

var HnReader = React.createClass[{  
    ...
}];

Di dalam objek adalah metode renderScene, yang dipanggil kapan pun route berubah. route dan navigator diteruskan sebagai argumen untuk metode ini. route berisi informasi tentang route saat ini [misalnya, nama route].

navigator berisi metode yang dapat digunakan untuk menavigasi di antara route yang berbeda. Di dalam metode renderScene, kita mendapatkan komponen yang ingin kita buat dengan meneruskan nama route saat ini ke objek ROUTES. Selanjutnya, kita membuat komponen dan melewati route, navigator, dan url sebagai atribut. Nantinya, kamu akan melihat bagaimana ini digunakan di dalam masing-masing komponen. Untuk saat ini, ingatlah bahwa ketika kamu ingin meneruskan data dari komponen utama ke komponen turunan, yang harus kamu lakukan adalah menambahkan atribut baru dan menggunakan data yang ingin kamu lewati sebagai nilainya.

renderScene: function[route, navigator] {

    var Component = ROUTES[route.name]; //get the component for this specific route

    //render the component and pass along the route, navigator and the url
    return [
        
    ];
},

Metode render adalah metode yang diperlukan saat membuat komponen karena bertanggung jawab untuk membuat antarmuka pengguna dari komponennya. Dalam metode ini, kita membuat komponen Navigator dan meneruskan beberapa atribut.

render: function[] {
    return [
       { return Navigator.SceneConfigs.FloatFromRight; }} />
    ];

},

Izinkan saya menjelaskan apa yang masing-masing atribut lakukan:

  • style digunakan untuk menambahkan style ke komponen.
  • initialRoute digunakan untuk menentukan route awal yang akan digunakan oleh navigator. Seperti yang kamu lihat, kami telah meneruskan sebuah objek yang berisi properti nama dengan nilainya yang diatur ke news_items. Objek ini adalah apa yang diteruskan ke argumen route dari metode renderScene, yang telah kita definisikan sebelumnya. Ini berarti kode khusus ini akan menjadikan komponen NewsItems secara default.
var Component = ROUTES[route.name]; 

url diatur ke string kosong karena kita tidak memiliki halaman web untuk ditampilkan secara default.

  • renderScene bertanggung jawab untuk merender komponen untuk route tertentu.
  • configureScene bertanggung jawab untuk menentukan animasi dan isyarat yang akan digunakan saat menavigasi antar route. Dalam kasus ini, kita meneruskan sebuah fungsi yang mengembalikan animasi FloatFromRight. Ini berarti bahwa, saat menavigasi ke route dengan indeks yang lebih tinggi, halaman baru melayang dari kanan ke kiri. Dan saat kembali, itu melayang kiri ke kanan. Ini juga menambahkan isyarat menggeser ke kiri sebagai sarana untuk kembali ke route sebelumnya.
[] => { return Navigator.SceneConfigs.FloatFromRight; }

Style didefinisikan setelah definisi komponen utama. Kita memanggil metode create dari objek StyleSheet dan meneruskannya dalam objek yang berisi gaya. Dalam kasus ini, kita hanya memiliki satu, yang menentukan bahwa ia akan menempati keseluruhan layar.

var styles = StyleSheet.create[{
  container: {
    flex: 1
  }
}];

Terakhir, kita mendaftarkan komponennya.

AppRegistry.registerComponent['HnReader', [] => HnReader];

Komponen NewsItem

Komponen NewsItem digunakan untuk merender item berita. Komponen khusus disimpan dalam direktori components. Di dalam direktori ini, buat news-items.js dan tambahkan kode berikut ke dalamnya:

'use strict';
var React = require['react-native'];

var {
  AppRegistry,
  StyleSheet,
  Text,
  ListView,
  View,
  ScrollView,
  TouchableHighlight,
  AsyncStorage
} = React;

var Button = require['react-native-button'];
var GiftedSpinner = require['react-native-gifted-spinner'];

var api = require['../src/api.js'];

var moment = require['moment'];

var TOTAL_NEWS_ITEMS = 10;

var NewsItems = React.createClass[{

    getInitialState: function[] {
        return {
          title: 'HN Reader',
          dataSource: new ListView.DataSource[{
            rowHasChanged: [row1, row2] => row1 !== row2,
          }],
          news: {},
          loaded: false
        }    
    },

    render: function[] {
        
        return [
            
                
                    
                        {this.state.title}
                    
                    
                    {  !this.state.loaded && 
                        
                    }
                    
                
                
                
                {
                    this.state.loaded && 
                    
                    
                    
                }
                
                
            
        ]; 
        
    },

    componentDidMount: function[] {
            
        AsyncStorage.getItem['news_items'].then[[news_items_str] => {

            var news_items = JSON.parse[news_items_str];

            if[news_items != null]{
                
                AsyncStorage.getItem['time'].then[[time_str] => {
                    var time = JSON.parse[time_str];
                    var last_cache = time.last_cache;
                    var current_datetime = moment[];

                    var diff_days = current_datetime.diff[last_cache, 'days'];
                    
                    if[diff_days > 0]{
                        this.getNews[];
                    }else{
                        this.updateNewsItemsUI[news_items];
                    }

                }];
                

            }else{
                this.getNews[];
            }

        }].done[];

    },

    renderNews: function[news] {
        return [
            
            
                {news.title}
            
            
        ];
    },

    viewPage: function[url]{
        this.props.navigator.push[{name: 'web_page', url: url}];
    },

    updateNewsItemsUI: function[news_items]{
    
        if[news_items.length == TOTAL_NEWS_ITEMS]{

            var ds = this.state.dataSource.cloneWithRows[news_items];
            this.setState[{
              'news': ds,
              'loaded': true
            }];

        }
        
    },

    updateNewsItemDB: function[news_items]{

        if[news_items.length == TOTAL_NEWS_ITEMS]{
            AsyncStorage.setItem['news_items', JSON.stringify[news_items]];
        }

    },

    getNews: function[] {   
        
        var TOP_STORIES_URL = '//hacker-news.firebaseio.com/v0/topstories.json';
        var news_items = [];

        AsyncStorage.setItem['time', JSON.stringify[{'last_cache': moment[]}]];

        api[TOP_STORIES_URL].then[
          [top_stories] => {
                
                for[var x = 0; x  {

                            news_items.push[story];
                            this.updateNewsItemsUI[news_items];
                            this.updateNewsItemDB[news_items];

                        }
                    ];

                }
                

            }



        ];
        
        
    }

}];



var styles = StyleSheet.create[{
  container: {
    flex: 1
  },
  header: {
    backgroundColor: '#FF6600',
    padding: 10,
    flex: 1,
    justifyContent: 'space-between',
    flexDirection: 'row'
  },
  body: {
    flex: 9,
    backgroundColor: '#F6F6EF'
  },
  header_item: {
    paddingLeft: 10,
    paddingRight: 10,
    justifyContent: 'center'
  },
  header_text: {
    color: '#FFF',
    fontWeight: 'bold',
    fontSize: 15
  },
  button: {
    borderBottomWidth: 1,
    borderBottomColor: '#F0F0F0'
  },
  news_item: {
    paddingLeft: 10,
    paddingRight: 10,
    paddingTop: 15,
    paddingBottom: 15,
    marginBottom: 5
  },
  news_item_text: {
    color: '#575757',
    fontSize: 18
  }
}];

module.exports = NewsItems;

Langkah 1: Mengimpor Komponen & Library

Pertama, kita mengimpor komponen dan library yang kita butuhkan untuk komponen NewsItem. Kita juga membuat variabel global yang menyimpan jumlah item berita yang akan di-cache.

'use strict';
var React = require['react-native'];

var {
  AppRegistry,
  StyleSheet,
  Text,
  ListView,
  View,
  ScrollView,
  TouchableHighlight,
  AsyncStorage
} = React;

var Button = require['react-native-button'];
var GiftedSpinner = require['react-native-gifted-spinner'];

var api = require['../src/api.js'];

var moment = require['moment'];

var TOTAL_NEWS_ITEMS = 10;

Kita menggunakan beberapa komponen yang belum kita gunakan tadi.

  • Text digunakan untuk menampilkan teks dalam React Native.
  • View adalah blok bangunan dasar untuk membuat komponen. Anggap saja itu sebagai div di halaman web.
  • ListView digunakan untuk merender suatu array dari objek.
  • ScrollView digunakan untuk menambahkan scroll bar. React Native tidak seperti halaman web. Scroll bar tidak ditambahkan secara otomatis saat konten lebih besar dari tampilan atau layar. Itu sebabnya kita perlu menggunakan komponen ini.
  • TouchableHighlight digunakan untuk membuat komponen menanggapi event sentuhan.
  • AsyncStorage sebenarnya bukan komponen. Ini adalah API yang digunakan untuk menyimpan data lokal di React Native.
  • Button adalah komponen pihak ketiga untuk membuat tombol.
  • GiftedSpinner digunakan untuk membuat spinner saat memuat data dari jaringan.
  • api adalah modul khusus yang membungkus fetch, cara React Native untuk membuat permintaan jaringan. Ada banyak kode boilerplate yang dibutuhkan untuk mendapatkan data yang dikembalikan oleh permintaan jaringan dan oleh karena itu kita membungkusnya di dalam modul. Ini memungkinkan kita menulis lebih sedikit kode saat membuat permintaan jaringan.
  • moment adalah library yang digunakan untuk segala hal yang berhubungan dengan waktu.

Langkah 2: Membuat komponen NewsItems

Selanjutnya, kita membuat komponen NewsItems:

var NewsItems = React.createClass[{
    ...
}];

Komponen ini adalah fungsi getInitialState, yang digunakan untuk menentukan state default untuk komponen ini. Dalam React Native, state digunakan untuk menyimpan data yang tersedia di seluruh komponen. Di sini, kita menyimpan judul aplikasi, dataSource untuk komponen ListView, item news saat ini dan nilai boolean, loaded, yang memberitahu apakah item berita saat ini sedang dimuat dari jaringan atau tidak. Variabel loaded digunakan untuk menentukan apakah atau tidak untuk menampilkan spinner. Kita atur ke false sehingga spinner dapat dilihat secara default.

Setelah item berita dimuat, baik dari local storage atau dari jaringan, itu diset ke true untuk menyembunyikan spinner. dataSource digunakan untuk mendefinisikan blueprint dari sumber data yang digunakan untuk komponen ListView. Anggap saja sebagai class induk di mana setiap sumber data yang akan kamu definisikan akan mewarisinya. Hal ini memerlukan sebuah objek yang mengandung fungsi rowHasChanged, yang memberitahukan ListView untuk kembali merender ulang ketika sebuah baris telah berubah.

Akhirnya, berita objek berisi nilai awal untuk sumber data ListView.

getInitialState: function[] {
    return {
      title: 'HN Reader',
      dataSource: new ListView.DataSource[{
        rowHasChanged: [row1, row2] => row1 !== row2,
      }],
      news: {},
      loaded: false
    }    
},

Langkah 3: Mengimplementasikan Fungsi render

Fungsi render merender antarmuka pengguna untuk komponen ini. Pertama, kira bungkus semuanya dalam sebuah View. Kemudian, di dalamnya kita memiliki header dan body. Header berisi judul dan spinner. Body berisi ListView. Segala sesuatu di dalam body dibungkus di dalam ScrollView sehingga scroll bar akan secara otomatis ditambahkan jika konten melebihi ruang yang tersedia.

render: function[] {
    
    return [
        
            
                
                    {this.state.title}
                
                
                {  !this.state.loaded && 
                    
                }
                
            
            
            
            {
                this.state.loaded && 
                
                
                
            }
            
            
        
    ]; 
    
},

Di dalam header ada dua view:

  • satu berisi judul
  • satu berisi spinner

Kita melakukan itu dengan cara ini daripada mengeluarkan teks dan spinner secara langsung sehingga kita bisa mengendalikan styling dengan menggunakan flexbox, Kamu dapat melihat bagaimana hal ini dilakukan di bagian styling, nanti.

Kita dapat merujuk kepada judul yang disimpan di state-nya dengan menggunakan this.state, diikuti oleh nama properti. Seperti yang mungkin kamu perhatikan, setiap kali kita perlu merujuk pada sebuah objek, kita membungkusnya dengan kurung kurawal. Pada view yang lain, kita sedang memeriksa jika properti loaded di state diatur ke false dan, jika itu adalah, kita keluaran pemintal.

    {this.state.title}


{  !this.state.loaded && 
    
}

Berikutnya adalah body.

{
    this.state.loaded && 
    
    
    
}

Perhatikan bahwa kita telah mengirimkan atribut ref ke ScrollView. ref adalah atribut yang telah ditetapkan dalam React Native yang memungkinkan kita untuk menetapkan pengenal untuk sebuah komponen. Kami dapat menggunakan pengenal ini untuk merujuk ke komponennya dan memanggil metode-metodenya. Berikut adalah contoh bagaimana ini bekerja:

scrollToTop: function[]{
    this.refs.scrollView.scrollTo[0];
}

Kamu kemudian dapat memiliki tombol dan memanggil fungsi itu saat ditekan. Ini secara otomatis akan men-scroll ScrollView ke puncak komponen.

scroll to top

Kita tidak akan menggunakan ini di aplikasi, tetapi ada baiknya untuk tahu bahwa itu ada.

Di dalam ScrollView, kita memeriksa jika properti loaded di state sudah diset ke true. Jika itu true, itu berarti bahwa sumber data sudah tersedia untuk digunakan oleh ListView dan kita dapat merendernya.

{
    this.state.loaded && 
    
    
    
}

Kami telah meneruskan atribut berikut di ListView:

  • initialListSize digunakan untuk menentukan berapa banyak baris untuk dirender ketika komponen awalnya dipasang. Kita telah mengesetnya ke 1, yang berarti itu akan mengambil satu frame untuk membuat merender setiap baris. Saya telah mengesetnya ke 1 sebagai bentuk optimasi kinerja sehingga pengguna melihat sesuatu sesegera mungkin.
  • dataSource adalah sumber data yang untuk digunakan.
  • renderRow adalah fungsi yang digunakan untuk merender setiap baris dalam daftar.

Langkah 4: Mengimplementasikan Fungsi componentDidMount

Selanjutnya, kita memiliki fungsi componentDidMount, yang akan dipanggil ketika komponen ini dipasang:

componentDidMount: function[] {
        
    AsyncStorage.getItem['news_items'].then[[news_items_str] => {

        var news_items = JSON.parse[news_items_str];

        if[news_items != null]{
            
            AsyncStorage.getItem['time'].then[[time_str] => {
                var time = JSON.parse[time_str];
                var last_cache = time.last_cache;
                var current_datetime = moment[];

                var diff_days = current_datetime.diff[last_cache, 'days'];
                
                if[diff_days > 0]{
                    this.getNews[];
                }else{
                    this.updateNewsItemsUI[news_items];
                }

            }];
            

        }else{
            this.getNews[];
        }

    }].done[];

},

Dalam fungsi tersebut, kita mencoba untuk mengambil item berita yang saat ini disimpan dalam local storage. Kita menggunakan metode getItem dari API AsyncStorage. Itu mengembalikan sebuah promise sehingga kita bisa mendapatkan akses ke data yang dikembalikan dengan memanggil metode then kemudian meneruskannya sebuah dalam fungsi:

AsyncStorage.getItem['news_items'].then[[news_items_str] => {
    ...
}].done[];

AsyncStorage hanya dapat menyimpan string data sehingga kita menggunakan JSON.parse untuk mengkonversi string JSON kembali ke objek JavaScript. Jika itu null, kita memanggil metode getNews, yang mengambil data dari jaringan.

var news_items = JSON.parse[news_items_str];

if[news_items != null]{
    ...
}else{
    this.getNews[];
}

Jika tidak kosong, kita menggunakan AsyncStorage untuk mengambil waktu terakhir dari item berita yang disimpan dalam local storage. Kita kemudian membandingkannya dengan waktu saat ini. Jika perbedaan ini setidaknya sehari [24 jam], kita mengambil item berita dari jaringan. Jika tidak, kita menggunakan yang ada di penyimpanan lokal.

AsyncStorage.getItem['time'].then[[time_str] => {
    var time = JSON.parse[time_str];
    var last_cache = time.last_cache; //extract the last cache time
    var current_datetime = moment[]; //get the current time
    
    //get the difference in days
    var diff_days = current_datetime.diff[last_cache, 'days'];
    
    if[diff_days > 0]{
        this.getNews[]; //fetch from the network
    }else{
        this.updateNewsItemsUI[news_items]; //use the one in the cache
    }

}];

Langkah 5: Mengimplementasikan Fungsi renderNews

Berikutnya adalah fungsi untuk merender setiap baris dalam daftar. Sebelumnya di ListView, kita telah mendefinisikan atribut renderRow, yang memiliki nilai this.renderNews. Ini adalah fungsi itu.

Item saat ini dalam perulangan dilteruskan sebagai  sebuah argumen untuk fungsi ini. Hal ini memungkinkan kita untuk mengakses title dan url dari setiap item berita. Semuanya terbungkus di dalam komponen TouchableHighlight dan di dalamnya kita tampilkan judul setiap item berita.

Komponen TouchableHighlight menerima atribut onPress, yang menetapkan fungsi yang mengeksekusi ketika pengguna mengetuk item-nya. Di sini kita panggil fungsi viewPage dan mengikat URL untuk itu. underlayColor menentukan warna background dari komponen ketika diketuk.

renderNews: function[news] {
    return [
        
        
            {news.title}
        
        
    ];
},

Pada fungsi viewPage, kami mendapatkan atribut navigator yang telah kita teruskan sebelumnya dari index.android.js via props. Di React Native, props digunakan untuk mengakses atribut yang diteruskan dari komponen induk. Kita menyebutnya sebagai this.props, diikuti oleh nama atribut.

Di sini, kita menggunakan this.props.navigator untuk merujuk ke objek navigator. Kita kemudian memanggil metode push untuk mendorong route web_page ke navigator dengan URL halaman web yang akan dibuka oleh komponen WebPage. Hal ini membuat transisi aplikasi ke komponen WebPage.

viewPage: function[url]{
    this.props.navigator.push[{name: 'web_page', url: url}];
},

Langkah 6: Mengimplementasikan Fungsi updateNewsItemsUI

Fungsi updateNewsItemsUI memperbarui sumber data dan state berdasarkan array item berita yang diteruskan sebagai sebuah argumen. Kita hanya melakukannya jika total news_items sama dengan nilai yang kita tetapkan sebelumnya untuk TOTAL_NEWS_ITEMS. Di React Native, memperbarui state memicu antarmuka pengguna untuk merender ulang. Ini berarti bahwa panggilan setState dengan sumber data baru me-refresh antarmuka pengguna dengan item baru.

updateNewsItemsUI: function[news_items]{
    
    if[news_items.length == TOTAL_NEWS_ITEMS]{

        var ds = this.state.dataSource.cloneWithRows[news_items]; //update the data source

        //update the state
        this.setState[{
          'news': ds,
          'loaded': true
        }];

    }
    
},

Langkah 7: Memperbarui Local Storage

Fungsi updateNewsItemDB memperbarui berita yang disimpan dalam local storage. Kita menggunakan fungsi JSON.stringify untuk mengkonversi array ke dalam sebuah string JSON sehingga kita dapat menyimpannya menggunakan AsyncStorage.

updateNewsItemDB: function[news_items]{

    if[news_items.length == TOTAL_NEWS_ITEMS]{
        AsyncStorage.setItem['news_items', JSON.stringify[news_items]];
    }

},

Langkah 8: Mengambil Item Berita

Fungsi getNews memperbarui item local storage yang terakhir kali menyimpan data yang di-cache, mengambil item berita dari API Hacker News, memperbarui antarmuka pengguna dan local storage berdasarkan item baru yang diambil.

getNews: function[] {   
    
    var TOP_STORIES_URL = '//hacker-news.firebaseio.com/v0/topstories.json';
    var news_items = [];

    AsyncStorage.setItem['time', JSON.stringify[{'last_cache': moment[]}]];

    api[TOP_STORIES_URL].then[
      [top_stories] => {
            
            for[var x = 0; x  {

                        news_items.push[story];
                        this.updateNewsItemsUI[news_items];
                        this.updateNewsItemDB[news_items];

                    }
                ];

            }
        }
    ];
    
}

Sumber cerita teratas di API Hacker News mengembalikan array yang terlihat seperti ini:

[ 10977819, 10977786, 10977295, 10978322, 10976737, 10978069, 10974929, 10975813, 10974552, 10978077, 10978306, 10973956, 10975838, 10974870...

Ini adalah pengidentifikasi item teratas yang diposting di Hacker News. Itulah mengapa kita perlu melakukan perulangan melalui array ini dan membuat request jaringan untuk setiap item untuk mendapatkan rincian sebenarnya, seperti judul dan URL.

Kita kemudian mendorongnya ke array news_items dan memanggil fungsi updateNewsItemsUI dan updateNewsItemDB untuk memperbarui antarmuka pengguna dan local storage.

for[var x = 0; x  {

            news_items.push[story];
            this.updateNewsItemsUI[news_items];
            this.updateNewsItemDB[news_items];

        }
    ];

}

Langkah 9: Styling

Tambahkan style berikut ini:

var styles = StyleSheet.create[{
  container: {
    flex: 1
  },
  header: {
    backgroundColor: '#FF6600',
    padding: 10,
    flex: 1,
    justifyContent: 'space-between',
    flexDirection: 'row'
  },
  body: {
    flex: 9,
    backgroundColor: '#F6F6EF'
  },
  header_item: {
    paddingLeft: 10,
    paddingRight: 10,
    justifyContent: 'center'
  },
  header_text: {
    color: '#FFF',
    fontWeight: 'bold',
    fontSize: 15
  },
  button: {
    borderBottomWidth: 1,
    borderBottomColor: '#F0F0F0'
  },
  news_item: {
    paddingLeft: 10,
    paddingRight: 10,
    paddingTop: 15,
    paddingBottom: 15,
    marginBottom: 5
  },
  news_item_text: {
    color: '#575757',
    fontSize: 18
  }
}];

Sebagian besar itu adalah CSS standar, namun perhatikan bahwa kita telah mengganti tanda hubung dengan sintaks kurung kurawal. Ini bukan karena kita mendapatkan kesalahan sintaks jika kita menggunakan sesuatu seperti padding-left. Hal ini karena diharuskan oleh React Native. Juga perhatikan bahwa tidak semua properti css dapat digunakan.

Yang dikatakan, berikut ini adalah beberapa deklarasi yang mungkin tidak terlalu intuitif, terutama jika kamu belum pernah menggunakan flexbox sebelumnya:

container: {
    flex: 1
},
header: {
    backgroundColor: '#FF6600',
    padding: 10,
    flex: 1,
    justifyContent: 'space-between',
    flexDirection: 'row'
},
body: {
    flex: 9,
    backgroundColor: '#F6F6EF'
},

Berikut ini adalah versi sederhana dari markup untuk komponen NewsItems untuk membantumu memvisualisasikan itu:

    
        ...
    
    
        ...
    

Kami telah menetapkan container ke flex: 1, yang berarti menempati seluruh layar. Di dalam container kita memiliki header dan body, yang telah kita set ke flex: 1 dan flex: 9, masing-masingnya. Dalam kasus ini, flex: 1 tidak akan menempati seluruh layar karena header memiliki saudara kandung. Keduanya akan berbagi keseluruhan layar. Ini berarti bahwa seluruh layar akan dibagi menjadi sepuluh bagian karena kita memiliki flex: 1 dan flex: 9. Nilai untuk flex untuk masing-masing saudara kandung ditambahkan.

header menempati 10% dari layar dan body menempati 90% dari itu. Ide dasarnya adalah memilih nomor yang akan mewakili tinggi atau lebar seluruh layar dan kemudian masing-masing  saudara kandung mengambil sepotong dari nomor ini Jangan berlebihan dengan ini, meskipun. Kamu tidak ingin menggunakan 1000 kecuali kamu ingin men-deploy aplikasi mu di bioskop. Saya menemukan sepuluh menjadi nomor ajaib saat bekerja dengan tinggi badan.

Untuk header, kita telah menetapkan gaya berikut:

header: {
    backgroundColor: '#FF6600',
    padding: 10,
    flex: 1,
    justifyContent: 'space-between',
    flexDirection: 'row'
},

Dan untuk me-refresh ingatanmu, berikut adalah markup sederhana dari apa yang ada di dalam header:

    ...


    ...

Dan dengan style yang ditambahkan kepadanya:

header_item: {
    paddingLeft: 10,
    paddingRight: 10,
    justifyContent: 'center'
},

Kita telah menetapkan flexDirection ke row dan justifyContent ke space-between pada induknya, yaitu header. Ini berarti turunannya akan merata, dengan turunan pertama di awal baris dan turunan terakhir di akhir baris.

Secara default flexDirection diatur ke column, yang berarti bahwa setiap turunan menempati seluruh baris karena gerakan horisontal. Menggunakan row akan membuat aliran vertikal sehingga setiap turunan akan berdampingan. Jika kamu masih bingung tentang Flexbox atau kamu ingin mempelajari lebih lanjut tentang hal itu, kemudian periksa CSS: Flexbox Essentials.

Terakhir, menampakkan komponen untuk dunia luar:

module.exports = NewsItems;

Kesimpulan

Pada titik ini, kamu seharusnya memiliki ide bagus tentang bagaimana melakukan banyak hal dengan cara React Native. Secara khusus, kamu telah belajar bagaimana untuk membuat sebuah proyek React Native baru, menginstal library pihak ketiga melalui npm, menggunakan berbagai komponen dan menambahkan styling ke aplikasi.

Pada artikel selanjutnya, kita akan melanjutkan dengan menambahkan komponen WebPage untuk aplikasi pembaca berita. Jangan ragu untuk meninggalkan pertanyaan atau komentar pada bagian komentar di bawah ini.

Bài mới nhất

Chủ Đề