ahmadajah03 Fri Nov 2020 1 year ago

Memulai dengan React Native

Dengan popularitas smartphone yang terus meningkat, pengembang mencari solusi untuk membangun aplikasi seluler. Untuk pengembang dengan latar belakang web, kerangka kerja seperti Cordova dan Ionic, React Native, NativeScript, dan Flutter memungkinkan kita membuat aplikasi seluler dengan bahasa yang sudah kita kenal: HTML, XML, CSS, dan JavaScript.

Dalam panduan ini, kita akan melihat lebih dekat pada React Native. Anda akan mempelajari dasar-dasar mutlak untuk memulainya. Secara khusus, kami akan membahas yang berikut:

  • apa itu React Native
  • apa itu Expo
  • cara mengatur lingkungan pengembangan React Native menggunakan Expo
  • cara membuat aplikasi dengan React Native

Prasyarat

Tutorial ini mengasumsikan bahwa Anda berasal dari latar belakang pengembangan web. Persyaratan minimum bagi Anda untuk dapat mengikuti tutorial ini dengan percaya diri adalah mengetahui HTML, CSS, dan JavaScript. Anda juga harus tahu cara menginstal perangkat lunak pada sistem operasi Anda dan bekerja dengan baris perintah. Kami juga akan menggunakan beberapa sintaks ES6, jadi akan membantu jika Anda mengetahui sintaks ES6 dasar juga. Pengetahuan tentang React sangat membantu tetapi tidak diperlukan.

Apa itu React Native?

React Native adalah kerangka kerja untuk membangun aplikasi yang bekerja di Android dan iOS. Ini memungkinkan Anda membuat aplikasi asli nyata menggunakan JavaScript dan React. Ini berbeda dari kerangka kerja seperti Cordova, di mana Anda menggunakan HTML untuk membangun UI, yang kemudian hanya akan ditampilkan dalam peramban seluler terintegrasi perangkat (WebView). React Native memiliki komponen bawaan yang dikompilasi ke komponen UI asli, sementara kode JavaScript Anda dijalankan melalui mesin virtual. Ini membuat React Native lebih berkinerja daripada Cordova.

Keuntungan lain dari React Native adalah kemampuannya untuk mengakses fitur perangkat asli. Ada banyak plugin yang dapat Anda gunakan untuk mengakses fitur perangkat asli, seperti kamera dan berbagai sensor perangkat . Jika Anda membutuhkan fitur khusus platform yang belum diimplementasikan, Anda juga dapat membuat modul asli Anda sendiri - meskipun itu akan mengharuskan Anda memiliki pengetahuan yang cukup tentang platform asli yang ingin Anda dukung (Java atau Kotlin). untuk Android, dan Objective C atau Swift untuk iOS).

Jika Anda datang ke sini dan baru mengenal React, Anda mungkin bertanya-tanya apa itu. React adalah pustaka JavaScript untuk Web untuk membangun antarmuka pengguna. Jika Anda terbiasa dengan MVC, pada dasarnya ini adalah Tampilan di MVC. Tujuan utama React adalah memungkinkan pengembang membangun komponen UI yang dapat digunakan kembali. Contoh komponen ini termasuk tombol, penggeser, dan kartu. React Native mengambil ide untuk membuat komponen UI yang dapat digunakan kembali dan membawanya ke dalam pengembangan aplikasi seluler.

Apa itu Expo?

Sebelum datang ke sini, Anda mungkin pernah mendengar tentang Expo . Itu bahkan disebutkan dalam dokumen resmi React Native, jadi Anda mungkin bertanya-tanya apa itu.

Sederhananya, Expo memungkinkan Anda membangun aplikasi React Native tanpa sakit kepala awal yang datang dengan menyiapkan lingkungan pengembangan Anda. Ini hanya mengharuskan Anda untuk menginstal Node di mesin Anda, dan aplikasi klien Expo di perangkat atau emulator Anda.

Tapi begitulah Expo awalnya dijual. Pada kenyataannya, ini lebih dari itu. Expo sebenarnya adalah platform yang memberi Anda akses ke alat, perpustakaan, dan layanan untuk membangun aplikasi Android dan iOS lebih cepat dengan React Native. Expo hadir dengan SDK yang mencakup sebagian besar API yang dapat Anda minta dalam platform pengembangan aplikasi seluler:

Itu hanya beberapa dari API yang Anda dapatkan aksesnya di luar kotak jika Anda mulai membangun aplikasi React Native dengan Expo. Tentu saja, API ini juga tersedia untuk Anda melalui modul asli jika Anda mengembangkan aplikasi Anda menggunakan pengaturan standar React Native.

Plain React Native atau Expo?

Pertanyaan sebenarnya adalah yang mana yang harus dipilih - React Native atau Expo? Benar-benar tidak ada jawaban benar atau salah. Itu semua tergantung pada konteks dan kebutuhan Anda. Tapi saya rasa aman untuk berasumsi bahwa Anda membaca tutorial ini karena Anda ingin segera memulai dengan React Native. Jadi saya akan melanjutkan dan merekomendasikan Anda untuk memulai dengan Expo. Cepat, sederhana, dan mudah disiapkan. Anda dapat langsung mengutak-atik kode React Native dan merasakan apa yang ditawarkan hanya dalam beberapa jam.

Tetapi ketika Anda mulai memahami konsep yang berbeda, dan ketika kebutuhan akan fitur asli yang berbeda muncul, Anda mungkin menemukan bahwa Expo agak membatasi. Ya, ini memiliki banyak fitur asli yang tersedia, tetapi tidak semua modul asli yang tersedia untuk proyek React Native standar didukung.

Catatan: proyek seperti unimodules mulai menutup celah antara proyek React Native standar dan proyek Expo, karena memungkinkan pengembang untuk membuat modul asli yang berfungsi baik untuk React Native dan ExpoKit.

Menyiapkan Lingkungan Pengembangan Asli React

Untuk segera memulai dengan React Native, metode yang disarankan adalah mengatur Expo .

 

Satu-satunya prasyarat untuk menyiapkan Expo adalah Anda harus menginstal Node.js di mesin Anda. Untuk melakukan ini, Anda dapat menuju ke halaman unduhan Node resmi dan mengambil binari yang relevan untuk sistem Anda, atau Anda dapat menggunakan pengelola versi , yang memungkinkan Anda untuk menginstal beberapa versi Node dan beralih di antara mereka sesuka hati.

Setelah Anda menginstal Node.js, instal Expo CLI. Ini digunakan untuk membuat, melayani, mengemas, dan menerbitkan proyek:

npm install -g expo-cli

Selanjutnya, instal Yarn, manajer paket pilihan untuk Expo:

npm install -g yarn

Hanya itu yang ada di sana! Langkah selanjutnya adalah mengunduh Aplikasi klien Expo untuk Android atau iOS . Perhatikan bahwa ini adalah satu-satunya cara Anda dapat menjalankan aplikasi Expo saat Anda masih dalam pengembangan. Saat Anda siap untuk mengirimkan aplikasi, Anda dapat mengikuti panduan ini untuk membuat biner mandiri untuk iOS dan Android yang dapat dikirimkan ke Apple App Store dan Google Play Store.

Apa Yang Akan Kami Bangun

Sekarang lingkungan pengembangan Anda sudah siap, kita dapat melihat aplikasi yang akan kita buat - aplikasi pencarian Pokémon. Ini akan memungkinkan pengguna untuk mengetik nama Pokémon ke dalam kotak input, sebelum mengambil detail Pokémon dari API eksternal dan menampilkannya kepada pengguna.

Inilah yang akan terlihat seperti:

Seperti biasa, Anda dapat menemukan kode sumber untuk ini di repo GitHub kami .

Bootstrap Aplikasi

Di terminal Anda, jalankan perintah berikut untuk membuat proyek React Native baru menggunakan Expo:

expo init RNPokeSearch

Di bawah Alur Kerja Terkelola , pilih kosong . Secara default, ini akan menginstal dependensi menggunakan Yarn.

Anda mungkin bertanya apa alur kerja Terkelola dan alur kerja Telanjang ini. Ini adalah dua jenis alur kerja yang didukung Expo. Dengan alur kerja yang terkelola, Anda hanya perlu berurusan dengan JavaScript dan Expo mengatur segalanya untuk Anda. Saat berada di alur kerja Bare , Anda memiliki kendali penuh atas kode asli. Ini memberi Anda kebebasan yang sama dengan React Native CLI, tetapi dengan bonus tambahan dari pustaka dan layanan Expo. Anda dapat mengunjungi halaman intro terkelola vs telanjang ini jika Anda ingin mempelajari lebih lanjut tentang alur kerja di Expo.

Sama seperti di lingkungan web, Anda dapat menginstal pustaka untuk dengan mudah menerapkan berbagai jenis fungsionalitas di React Native. Setelah proyek dibuat, kita perlu menginstal beberapa dependensi: pokemon dan axios . Yang pertama digunakan untuk memverifikasi jika teks yang dimasukkan di kotak pencarian adalah nama Pokémon asli, sedangkan axios digunakan untuk membuat permintaan HTTP ke API yang kita gunakan, yaitu PokeAPI :

yarn add pokemon axios

React Native Project Directory Structure

Sebelum kita melanjutkan ke pengkodean, pertama-tama mari kita lihat struktur direktori dari proyek React Native yang dibuat dengan Expo:

Berikut ini rincian file dan folder terpenting yang perlu Anda ingat:

  • App.js: file proyek utama. Di sinilah Anda akan mulai mengembangkan aplikasi Anda. Setiap perubahan yang Anda buat pada file ini akan tercermin di layar.
  • src: bertindak sebagai folder utama yang menyimpan semua kode sumber yang terkait dengan aplikasi itu sendiri. Perhatikan bahwa ini tidak termasuk dalam proyek default yang dibuat oleh Expo CLI. Nama folder ini bisa apa saja. Beberapa orang juga menggunakannya app.
  • assets: ini adalah tempat aset aplikasi seperti ikon dan layar pembuka disimpan.
  • package.json: di mana nama dan versi pustaka yang Anda instal untuk proyek ini ditambahkan.
  • node_modules: tempat perpustakaan yang Anda instal disimpan. Perhatikan bahwa ini sudah berisi banyak folder sebelum Anda menginstal kedua pustaka tersebut sebelumnya. Ini karena React Native juga memiliki dependensinya sendiri. Hal yang sama berlaku untuk semua pustaka lain yang Anda instal.

Jangan pedulikan sisa folder dan file untuk saat ini, karena kami tidak akan membutuhkannya saat baru memulai.

Menjalankan Aplikasi

Pada titik ini, Anda sekarang dapat menjalankan aplikasi dengan menjalankan perintah di bawah ini. Pastikan Anda telah menginstal klien Expo yang sesuai ( Android atau iOS ) untuk ponsel Anda dan terhubung ke jaringan yang sama dengan komputer Anda sebelum melakukannya. Jika Anda tidak memiliki perangkat Android atau iOS yang dapat Anda uji, Anda dapat menggunakan Android Studio Emulator atau simulator iOS sehingga Anda dapat menjalankan aplikasi di komputer Anda:

yarn start

Setelah berjalan, itu akan menampilkan kode QR:

Buka aplikasi klien Expo Anda, dan di tab proyek, klik Pindai Kode QR . Ini akan membuka aplikasi di perangkat Android atau iOS Anda. Jika Anda menjalankan emulator, Anda dapat menekan i untuk menjalankannya di simulator iOS atau a menjalankannya di emulator Android.

Jika Anda menguji pada perangkat nyata, goyangkan sehingga menu pengembang akan muncul.

Pastikan Fast Refresh diaktifkan. Ini memungkinkan Anda untuk secara otomatis memuat ulang perubahan yang Anda buat pada komponen Anda.

Coding Aplikasi

Expo memiliki banyak komponen bawaan yang dapat Anda gunakan untuk mencapai apa yang Anda inginkan. Cukup gali dokumentasi API dan Anda akan menemukan informasi tentang bagaimana menerapkan apa yang Anda butuhkan. Dalam kebanyakan kasus, Anda memerlukan komponen UI tertentu atau SDK yang berfungsi dengan layanan yang ingin Anda gunakan. Lebih sering daripada tidak, berikut ini alur kerja Anda:

 

  1. Cari paket yang sudah ada yang mengimplementasikan apa yang Anda inginkan.
  2. Pasang itu.
  3. Hubungkan itu. Ini hanya diperlukan jika Anda berada di alur kerja kosong Expo dan paket yang Anda instal memiliki dependensi asli yang sesuai.
  4. Gunakan dalam proyek Anda.

Sekarang setelah Anda menyiapkan lingkungan Anda dan mempelajari sedikit tentang alur kerja, kami siap untuk mulai membuat kode aplikasi.

Pertama, mari kita perancah file yang kita perlukan. Ini src/Main.js juga src/components/Pokemon.js. The Main komponen akan memegang kode untuk menampilkan input pencarian dan query API, sedangkan Pokemon komponen akan digunakan untuk menampilkan data Pokemon yang dikembalikan:

mkdir -p src/components
touch src/Main.js
touch src/components/Pokemon.js

Tambahkan beberapa konten tiruan ke kedua file:

// src/Main.js
import React, { Component } from 'react';

export default class Main extends Component {
  render() {
    return null;
  }
}
// src/components/Pokemon.js
import  React  from  'react';

const  Pokemon  =  ()  =>  null;

Selanjutnya, ganti konten App.js file dengan kode berikut:

import React from 'react';
import Main from './src/Main';

function App() {
  return <Main />;
}

export default App;

Baris pertama pada kode di atas mengimpor kode React. Anda perlu mengimpor kelas ini kapan pun Anda ingin membuat komponen.

Baris kedua adalah tempat kami mengimpor Main komponen khusus . Kami akan mengisinya nanti, tetapi untuk saat ini, ketahuilah bahwa di sinilah kami akan meletakkan sebagian besar kode kami.

Setelah itu kita buat komponen dengan membuat fungsi baru. Semua fungsi ini lakukan adalah mengembalikan Main komponen.

Terakhir, kami mengekspor kelas agar dapat diimpor dan dirender oleh Expo.

Selanjutnya, dalam src/Main.js file dan tambahkan yang berikut ini:

// src/Main.js
import React, { Component } from 'react';
import {
  SafeAreaView,
  View,
  Text,
  TextInput,
  Button,
  Alert,
  StyleSheet,
  ActivityIndicator,
} from 'react-native';

Baris kedua mengimpor komponen yang dibangun ke dalam React Native. Inilah yang dilakukan masing-masing:

  • SafeAreaView: untuk merender konten dalam batas area aman perangkat. Ini secara otomatis menambahkan bantalan yang membungkus kontennya sehingga tidak akan ditampilkan pada takik kamera dan area perumahan sensor perangkat.
  • View: blok penyusun UI dasar. Ini terutama digunakan sebagai pembungkus untuk semua komponen lainnya sehingga terstruktur sedemikian rupa sehingga Anda dapat menatanya dengan mudah. Anggap saja sama dengan <div>. Jika Anda ingin menggunakan Flexbox, Anda harus menggunakan komponen ini.
  • Text: untuk menampilkan teks.
  • TextInput: komponen UI untuk memasukkan teks. Teks ini dapat berupa teks biasa, email, kata sandi, atau papan angka.
  • Button: untuk menampilkan tombol khusus platform. Komponen ini terlihat berbeda berdasarkan platform yang dijalankannya. Jika itu Android, itu menggunakan Desain Material. Jika itu iOS, itu menggunakan Cupertino.
  • Alert: untuk menampilkan lansiran dan petunjuknya.
  • ActivityIndicator: untuk menampilkan indikator animasi pemuatan.
  • StyleSheet: untuk menentukan gaya komponen.

Selanjutnya, impor pustaka yang kami instal sebelumnya:

import axios from 'axios';
import pokemon from 'pokemon';

Serta Pokemon komponen khusus yang digunakan untuk menampilkan data Pokémon:

import Pokemon from "./components/Pokemon";

Catatan: jika Expo tidak dapat menyelesaikan komponen Pokemon(atau lainnya), coba mulai ulang server.

Karena mendapatkan data Pokémon yang diperlukan melibatkan pembuatan dua permintaan API, kita harus menetapkan URL dasar API sebagai konstanta:

const POKE_API_BASE_URL = 'https://pokeapi.co/api/v2';

Selanjutnya, tentukan kelas komponen dan inisialisasi statusnya:

export default class Main extends Component {
  constructor(props) {
    super(props)

    this.state = {
      isLoading: false, // decides whether to show the activity indicator or not
      searchInput: '', // the currently input text
      name: '', // Pokémon name
      pic: '', // Pokémon image URL
      types: [], // Pokémon types array
      desc: '', // Pokémon description
    };
  }

  render() {
    return null;
  }
}

Dalam kode di atas, kami mendefinisikan komponen utama aplikasi. Anda dapat melakukan ini dengan mendefinisikan kelas ES6 dan membuatnya memperluas Component kelas React . Ini adalah cara lain untuk mendefinisikan komponen di React. Dalam App.js file tersebut, kami membuat komponen fungsional . Kali ini kami membuat komponen berbasis kelas .

Perbedaan utama antara keduanya adalah komponen fungsional hanya digunakan untuk tujuan presentasi. Komponen fungsional tidak perlu mempertahankan statusnya sendiri karena semua data yang dibutuhkan hanya diteruskan melalui props. Di sisi lain, komponen berbasis kelas mempertahankan statusnya sendiri dan biasanya mereka yang meneruskan data ke komponen fungsional. Perhatikan bahwa ini adalah cara tradisional untuk membuat komponen di React. Pendekatan yang lebih modern adalah tetap menggunakan komponen fungsional dan menggunakan pengait status untuk mengelola status - meskipun dalam tutorial ini kita hanya akan membuat semuanya tetap sederhana dan tetap menggunakan komponen berbasis kelas.

Jika Anda ingin mempelajari lebih lanjut tentang perbedaan antara fungsional dan komponen berbasis kelas, baca tutorial “ Fungsional vs Komponen Kelas di React ”.

Kembali ke kode, kami menginisialisasi status di dalam komponen kami. Anda mendefinisikannya sebagai objek JavaScript biasa. Setiap data yang masuk ke status harus bertanggung jawab untuk mengubah apa yang dirender oleh komponen. Dalam hal ini, kami memasukkan isLoading untuk mengontrol visibilitas indikator aktivitas dan searchInput untuk melacak nilai input di kotak pencarian.

Ini adalah konsep penting untuk diingat. Komponen built-in React Native, dan bahkan komponen kustom yang Anda buat, menerima properti yang mengontrol berikut ini:

  • apa yang ditampilkan di layar (sumber data)
  • bagaimana mereka menyajikannya (struktur)
  • seperti apa (gaya)
  • tindakan apa yang harus dilakukan ketika pengguna berinteraksi dengannya (fungsi)

Kami akan membahas properti tersebut lebih detail di bagian selanjutnya. Untuk saat ini, ketahuilah bahwa nilai properti tersebut biasanya diperbarui melalui status.

Nilai negara bagian lainnya adalah untuk data Pokémon. Ini adalah praktik yang baik untuk menetapkan nilai awal dengan jenis data yang sama yang Anda harapkan untuk disimpan nanti - karena ini juga berfungsi sebagai dokumentasi.

Komponen Penataan dan Styling

Mari kembali ke definisi kelas komponen. Saat Anda memperluas Component kelas React , Anda harus menentukan render() metode. Ini berisi kode untuk mengembalikan UI komponen dan itu terdiri dari komponen React Native yang kita impor sebelumnya.

Setiap komponen memiliki seperangkat alat peraga sendiri. Ini pada dasarnya adalah atribut yang Anda berikan ke komponen untuk mengontrol aspek tertentu darinya. Dalam kode di bawah ini, kebanyakan dari mereka memiliki style prop, yang digunakan untuk memodifikasi gaya sebuah komponen. Anda dapat mengirimkan tipe data apa pun sebagai prop. Misalnya, onChangeText prop dari TextInput adalah fungsi, sedangkan types prop pada Pokemon adalah larik objek. Nanti di Pokemon komponen, Anda akan melihat bagaimana alat peraga akan digunakan.

Ganti render() metode Main.js dengan yang berikut ini:

render() {
  const { name, pic, types, desc, searchInput, isLoading } = this.state; // extract the Pokémon data from the state

  return (
    <SafeAreaView style={styles.wrapper}>
      <View style={styles.container}>
        <View style={styles.headContainer}>
          <View style={styles.textInputContainer}>
            <TextInput
              style={styles.textInput}
              onChangeText={(searchInput) => this.setState({ searchInput })}
              value={this.state.searchInput}
              placeholder="Search Pokémon"
            />
          </View>
          <View style={styles.buttonContainer}>
            <Button
              onPress={this.searchPokemon}
              title="Search"
              color="#0064e1"
            />
          </View>
        </View>

        <View style={styles.mainContainer}>
          {isLoading && <ActivityIndicator size="large" color="#0064e1" />}

          {!isLoading && (
            <Pokemon name={name} pic={pic} types={types} desc={desc} />
          )}
        </View>
      </View>
    </SafeAreaView>
  );
}

Menguraikan kode di atas, pertama-tama kita mengekstrak data status:

const { name, pic, types, desc, searchInput, isLoading } = this.state;

Selanjutnya, kami mengembalikan UI komponen, yang mengikuti struktur ini:

SafeAreaView.wrapper;
  View.container;
    View.headContainer;
      View.textInputContainer;
        TextInput;
      View.buttonContainer;
        Button;
    View.mainContainer;
      ActivityIndicator;
        Pokemon;

Struktur di atas dioptimalkan untuk menggunakan Flexbox. Lanjutkan dan tentukan gaya komponen di bagian bawah file:

const styles = StyleSheet.create({
  wrapper: {
    flex: 1,
  },
  container: {
    flex: 1,
    padding: 20,
    backgroundColor: '#F5FCFF',
  },
  headContainer: {
    flex: 1,
    flexDirection: 'row',
    marginTop: 100,
  },
  textInputContainer: {
    flex: 2,
  },
  buttonContainer: {
    flex: 1,
  },
  mainContainer: {
    flex: 9,
  },
  textInput: {
    height: 35,
    marginBottom: 10,
    borderColor: '#ccc',
    borderWidth: 1,
    backgroundColor: '#eaeaea',
    padding: 5,
  },
});

Di React Native, Anda mendefinisikan gaya dengan menggunakan StyleSheet.create() dan meneruskan objek yang berisi gaya Anda. Definisi gaya ini pada dasarnya adalah objek JavaScript, dan mengikuti struktur yang sama seperti gaya CSS biasa Anda:

element: {
  property: value;
}

The wrapper dan container diatur untuk flex: 1, yang berarti ia akan menempati keseluruhan ruang yang tersedia karena mereka tidak memiliki saudara kandung. React Native default-nya flexDirection: 'column', yang artinya akan meletakkan item flex secara vertikal.

Sebaliknya, ( flexDirection: 'row') menata item secara horizontal.

Ini berbeda untuk headContainer, karena meskipun diatur ke flex: 1, ia memiliki mainContainer saudara kandungnya. Ini berarti headContainer dan mainContainer keduanya akan berbagi ruang yang sama. mainContainerdiatur flex: 9 sedemikian rupa sehingga akan menempati sebagian besar ruang yang tersedia (sekitar 90%), sementara headContainer hanya akan menempati sekitar 10%.

Mari beralih ke konten headContainer. Ia memiliki textInputContainer dan buttonContainer sebagai anak-anaknya. Ini diatur ke flexDirection: 'row', sehingga anak-anaknya akan ditata secara horizontal. Prinsip yang sama berlaku dalam hal berbagi ruang: textInputContainer menempati dua pertiga dari ruang horizontal yang tersedia, sementara buttonContainer hanya menempati sepertiga.

Gaya lainnya cukup jelas saat Anda memiliki latar belakang CSS. Ingatlah untuk menghilangkan - dan mengatur karakter berikut menjadi huruf besar. Misalnya, jika Anda ingin mengatur background-color, padanan React Native adalah backgroundColor.

Catatan: tidak semua properti CSS yang tersedia di Web didukung di React Native. Misalnya, hal-hal seperti float atau properti tabel tidak didukung. Anda dapat menemukan daftar properti CSS yang didukung di dokumen untuk komponen Tampilan dan Teks . Seseorang juga telah menyusun Lembar Cheat React Native Styling , dan ada bagian gaya dalam dokumentasi untuk komponen React Native tertentu yang ingin Anda gunakan. Misalnya, berikut adalah properti gaya yang dapat Anda gunakan untuk komponen Image .

Penanganan Peristiwa dan Memperbarui Status

Sekarang mari kita uraikan kode untuk TextInput dan Button komponen. Di bagian ini, kita akan berbicara tentang penanganan acara, membuat permintaan HTTP, dan memperbarui status di React Native.

Mari kita mulai dengan memeriksa kode untuk TextInput:

<TextInput
  style={styles.textInput}
  onChangeText={(searchInput) => this.setState({ searchInput })}
  value={this.state.searchInput}
  placeholder="Search Pokémon"
/>

Pada kode di atas, kita mengatur fungsi untuk dieksekusi ketika pengguna memasukkan sesuatu ke dalam komponen. Menangani kejadian seperti ini mirip dengan cara penanganannya di DOM: Anda cukup meneruskan nama kejadian sebagai prop dan menyetel nilainya ke fungsi yang ingin Anda jalankan. Dalam kasus ini, kami melakukan inline karena kami hanya memperbarui status. Nilai yang dimasukkan oleh pengguna secara otomatis diteruskan sebagai argumen ke fungsi yang Anda berikan, jadi yang harus Anda lakukan hanyalah memperbarui status dengan nilai itu. Jangan lupa untuk menyetel nilai dari TextInput ke variabel status. Jika tidak, nilai yang dimasukkan oleh pengguna tidak akan ditampilkan saat mereka mengetik.

Selanjutnya, kita beralih ke Button komponen. Di sini, kami mendengarkan onPressa caranya:

<Button onPress={this.searchPokemon} title="Search" color="#0064e1" />

Setelah ditekan, searchPokemon() fungsi tersebut dijalankan. Tambahkan fungsi ini tepat di bawah render()metode. Fungsi ini menggunakan async...await pola karena melakukan permintaan HTTP adalah operasi asinkron. Anda juga dapat menggunakan Promises, tetapi untuk menjaga kode kami tetap ringkas, kami akan tetap menggunakan async / await sebagai gantinya. Jika Anda tidak terbiasa dengan teknik ini, pastikan untuk membaca " Kontrol Aliran di JS Modern ".

// src/Main.js
import React, { Component } from 'react';
...
export default class Main extends Component {
  ...

  render() { ... }

  searchPokemon = async () => {
    try {
      const pokemonID = pokemon.getId(this.state.searchInput); // check if the entered Pokémon name is valid

      this.setState({
        isLoading: true, // show the loader while request is being performed
      });

      const { data: pokemonData } = await axios.get(
        `${POKE_API_BASE_URL}/pokemon/${pokemonID}`
      );
      const { data: pokemonSpecieData } = await axios.get(
        `${POKE_API_BASE_URL}/pokemon-species/${pokemonID}`
      );

      const { name, sprites, types } = pokemonData;
      const { flavor_text_entries } = pokemonSpecieData;

      this.setState({
        name,
        pic: sprites.front_default,
        types: this.getTypes(types),
        desc: this.getDescription(flavor_text_entries),
        isLoading: false, // hide loader
      });
    } catch (err) {
      Alert.alert('Error', 'Pokémon not found');
    }
  };
}

const styles = StyleSheet.create({ ... });

Menguraikan kode di atas, pertama-tama kita periksa apakah nama Pokémon yang dimasukkan valid. Jika valid, ID Pokedex Nasional (jika Anda membuka tautan, itu adalah nomor di atas nama Pokémon) dikembalikan dan kami menyediakannya sebagai parameter untuk permintaan HTTP. Permintaan dibuat menggunakan get() metode axios , yang sesuai dengan permintaan HTTP GET. Setelah data tersedia, kami mengekstrak apa yang kami butuhkan dan memperbarui status.

Berikut getTypes() fungsinya. Yang dilakukannya hanyalah menetapkan kembali properti slot dan type jenis Pokémon ke id dan name:

getTypes = (types) =>
  types.map(({ slot, type }) => ({
    id: slot,
    name: type.name,
  }));

Berikut getDescription() fungsinya. Ini menemukan versi bahasa Inggris pertama dari flavor_text:

getDescription = (entries) =>
    entries.find((item) => item.language.name === 'en').flavor_text;

Tambahkan mereka setelah searchPokemon fungsi, seperti ini:

import React, { Component } from 'react';
...
export default class Main extends Component {
  ...

  render() { ... }

  searchPokemon = async () => { ... };
  getTypes = (types) => types.map( ... );
  getDescription = (entries) => entries.find( ... );
}

const styles = StyleSheet.create({ ... });

Komponen Pokémon

Sekarang aplikasi kita sedang mengambil data dari API, saatnya untuk memperluas Pokemon komponen yang kita hentikan sebelumnya, sehingga kita bisa menampilkan data tersebut. Buka src/components/Pokemon.js file dan ganti isinya dengan yang berikut:

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

const Pokemon = ({ name, pic, types, desc }) => {
  if (!name) {
    return null;
  }

  return (
    <View style={styles.mainDetails}>
      <Image source={{ uri: pic }} style={styles.image} resizeMode="contain" />
      <Text style={styles.mainText}>{name}</Text>

      <FlatList
        columnWrapperStyle={styles.types}
        data={types}
        numColumns={2}
        keyExtractor={(item) => item.id.toString()}
        renderItem={({ item }) => (
          <View style={[styles[item.name], styles.type]}>
            <Text style={styles.typeText}>{item.name}</Text>
          </View>
        )}
      />

      <View style={styles.description}>
        <Text>{desc}</Text>
      </View>
    </View>
  );
};

//
const styles = StyleSheet.create({
  mainDetails: {
    padding: 30,
    alignItems: 'center',
  },
  image: {
    width: 100,
    height: 100,
  },
  mainText: {
    fontSize: 25,
    fontWeight: 'bold',
    textAlign: 'center',
  },
  description: {
    marginTop: 20,
  },
  types: {
    flexDirection: 'row',
    marginTop: 20,
  },
  type: {
    padding: 5,
    width: 100,
    alignItems: 'center',
  },
  typeText: {
    color: '#fff',
  },
  normal: {
    backgroundColor: '#8a8a59',
  },
  fire: {
    backgroundColor: '#f08030',
  },
  water: {
    backgroundColor: '#6890f0',
  },
  electric: {
    backgroundColor: '#f8d030',
  },
  grass: {
    backgroundColor: '#78c850',
  },
  ice: {
    backgroundColor: '#98d8d8',
  },
  fighting: {
    backgroundColor: '#c03028',
  },
  poison: {
    backgroundColor: '#a040a0',
  },
  ground: {
    backgroundColor: '#e0c068',
  },
  flying: {
    backgroundColor: '#a890f0',
  },
  psychic: {
    backgroundColor: '#f85888',
  },
  bug: {
    backgroundColor: '#a8b820',
  },
  rock: {
    backgroundColor: '#b8a038',
  },
  ghost: {
    backgroundColor: '#705898',
  },
  dragon: {
    backgroundColor: '#7038f8',
  },
  dark: {
    backgroundColor: '#705848',
  },
  steel: {
    backgroundColor: '#b8b8d0',
  },
  fairy: {
    backgroundColor: '#e898e8',
  },
});

export default Pokemon;

Pada kode di atas, kami pertama kali memeriksa apakah name memiliki nilai yang salah. Jika ya, kami hanya kembali null, karena tidak ada yang perlu dirender.

Kami juga menggunakan dua komponen React Native bawaan yang baru:

  • Image: digunakan untuk menampilkan gambar dari Internet atau dari sistem file
  • FlatList: digunakan untuk menampilkan daftar

Seperti yang kita lihat sebelumnya, kita mengirimkan data Pokémon sebagai prop untuk komponen ini. Kita dapat mengekstrak props tersebut dengan cara yang sama seperti kita mengekstrak properti individu dari sebuah objek:

const Pokemon = ({ name, pic, types, desc }) => {
    // ..
};

The Image komponen membutuhkan source untuk diteruskan untuk itu. The source baik dapat gambar dari sistem file, atau, dalam kasus ini, gambar dari internet. Yang pertama membutuhkan gambar untuk dimasukkan menggunakan require(), sedangkan yang kedua membutuhkan URL gambar untuk digunakan sebagai nilai uri properti dari objek yang Anda berikan padanya.

resizeMode memungkinkan Anda untuk mengontrol bagaimana gambar akan diubah ukurannya berdasarkan penampungnya. Kami menggunakan contain, yang berarti akan mengubah ukuran gambar agar pas dengan penampungnya sambil tetap mempertahankan rasio aspeknya. Perhatikan bahwa wadah adalah Imagekomponen itu sendiri. Kami telah mengatur its width and height to 100, sehingga gambar akan diubah ukurannya ke dimensi tersebut. Jika gambar asli memiliki lebar yang lebih lebar dari tingginya, a width dari 100 akan digunakan, sedangkan heightakan menyesuaikan sesuai untuk mempertahankan rasio aspek. Jika dimensi gambar asli lebih kecil, itu hanya akan mempertahankan ukuran aslinya:

<Image source={{ uri: pic }} style={styles.image} resizeMode={"contain"} />

Berikutnya adalah FlatList komponen. Ini digunakan untuk merender daftar item. Dalam hal ini, kami menggunakannya untuk merender tipe Pokémon. Ini memerlukan data, yang merupakan larik berisi item yang ingin Anda render, dan renderItem, yang merupakan fungsi yang bertanggung jawab untuk merender setiap item di daftar. Item dalam iterasi saat ini dapat diakses dengan cara yang sama dengan alat peraga diakses dalam komponen fungsional:

<FlatList
  columnWrapperStyle={styles.types}
  data={types}
  numColumns={2}
  keyExtractor={(item) => item.id.toString()}
  renderItem={({ item }) => (
    <View style={[styles[item.name], styles.type]}>
      <Text style={styles.typeText}>{item.name}</Text>
    </View>
  )}
/>

Pada kode di atas, kami juga menyediakan props berikut:

  • columnWrapperStyle: digunakan untuk menentukan gaya untuk setiap kolom. Dalam kasus ini, kami ingin membuat setiap item daftar sebaris, jadi kami telah menentukan flexDirection: 'row'.
  • numColumns: jumlah kolom maksimum yang ingin Anda render untuk setiap baris di daftar. Dalam hal ini, kami telah menentukan 2, karena Pokemon hanya dapat memiliki paling banyak dua jenis.
  • keyExtractor: fungsi yang digunakan untuk mengekstrak kunci untuk setiap item. Anda sebenarnya dapat menghilangkan yang satu ini jika Anda meneruskan key prop ke komponen paling luar dari setiap item daftar.

Pada tahap ini, Anda sekarang dapat menguji aplikasi di perangkat atau emulator Anda:

yarn start

Saat berada di terminal, Anda dapat menekan a jika ingin menjalankan aplikasi di emulator Android atau i jika ingin menjalankannya di simulator iOS.

Harap perhatikan juga bahwa nama Pokémon harus dimulai dengan huruf kapital - misalnya, “Pikachu”, bukan “pikachu”.

Kesimpulan dan Langkah Selanjutnya

Itu dia! Dalam tutorial ini, Anda telah mempelajari cara mengatur lingkungan pengembangan React Native menggunakan Expo. Anda juga telah mempelajari cara membuat aplikasi React Native pertama Anda.

install react native example