Blog

Belajar React Native - React Native Components

by
published on
Belajar React Native - React Native Components

React Native memiliki elemen UI berbasis Component.

Component yang dapat dirender bisa dianggap sebagai widget.

Widget tersebut dapat dirender di layar perangkat mobile kita.

Widget bisa berupa teks, tombol, gambar, dan widget yang kita definisikan sendiri.

Aplikasi yang kita buat adalah kumpulan dari Component-Component sehingga membentuk suatu aplikasi mobile yang utuh.

Daftar Component bawaan yang bisa kita impor lengkapnya bisa Anda lihat di sini:

https://facebook.github.io/react-native/docs/getting-started

Di bagian Components.

Component adalah salah satu class yang berasal dari modul React.

Oleh karena itu, ketika kita mendefinisikan Component, kita harus mengimpor React dan Component terlebih dahulu dari modul React:

import React, { Component } from "react";

Walaupun begitu, Component dalam artian widget berasal dari modul React Native.

Sehingga ketika kita ingin menggunakan Component seperti Text, TextInput, maupun View, kita harus mengimpor modul React Native terlebih dahulu: 

import { Text, TextInput, View } from "react-native"

Dengan kata lain, jika kita ingin mendefinisikan Component sendiri, kita harus menggunakan kedua modul tadi.

Hal itu disebabkan karena definisi Component kita terdiri dari core widgets yang didapat dari React Native dan membutuhkan superclass Component yang berasal dari React:

import React, { Component } from "react";
import { Text } from "react-native";

class MyText extends Component{
	render(){
		return <Text>My Text Di Sini!</Text>;
	}
}

export default MyText;

Dan untuk menggunakan MyText :

return <MyText />;

Di sini tampak bahwa Component dalam artian widget, yakni Text , diimpor dari modul React Native.

Sementara, Component yang menjadi superclass dari MyText diimpor dari modul React.

Jadi, bisa kita katakan bahwa modul React Native memiliki library dari definsi Component dalam bentuk widget seperti Text, Image, dan lain-lain. 

Function dan Class Based Component

Ada dua jenis Component yang bisa kita definisikan dalam React Native.

Jenis pertama adalah Functional Component dan yang kedua adalah Class Based Component.

Functional Componenent adalah Component statis.

Component tersebut bersifat stateless dan perannya adalah hanya untuk ditampilkan.

Adapun Class Based Component adalah Component yang memiliki state dan lifecycle method.

Dengan adanya state dan lifecycle method, maka Component tersebut bisa memiliki konten yang dinamis.

Class Based Component disebut demikian karena dalam pendefinisiannya dibentuk sebuah class yang merupakan subclass dari class Component.

Berbeda dengan Functional Component yang pendefinisiannya dibentuk sebuah function.

Membuat Functional Component

Untuk membuat Functional Component, caranya cukup mudah.

Anda cukup mengimpor modul React dan React Native.

Selanjutnya buat sebuah fungsi JSX yang mereturn tag Component widget seperti View, Text, maupun Image, atau yang lainnya yang Anda bisa dapatkan dari modul React Native.

Sekarang saatnya kita praktekkan.

Pertama, buat sebuah project React Native bernama "FunctionalComponent":

react-native init FunctionalComponent

Kemudian, tunggu beberapa saat hingga React Native selesai menggenerate project.

Selanjutnya, setelah proses itu selesai, buka file App.js.

Saat ini isi dari file App.js seperti ini:

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 * @flow
 */

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

const instructions = Platform.select({
  ios: 'Press Cmd+R to reload,\n' + 'Cmd+D or shake for dev menu',
  android:
    'Double tap R on your keyboard to reload,\n' +
    'Shake or press menu button for dev menu',
});

type Props = {};
export default class App extends Component<Props> {
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>Welcome to React Native!</Text>
        <Text style={styles.instructions}>To get started, edit App.js</Text>
        <Text style={styles.instructions}>{instructions}</Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});

Sekarang ubah file App.js menjadi seperti ini:

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

const App = () => {
	return <Text>Hello World!</Text>
};

export default App;

Kemudian jalankan emulator Android, lalu jalankan program ini dengan perintah:

react-native run-android

Nanti tampilannya akan seperti ini:

Membuat Class Based Component

Untuk membuat Class Based Component, caranya mirip dengan Functional Component.

Pertama Anda harus mengimpor modul React dan React Native.

Selanjutnya buat sebuah class JSX yang diturunkan dari class Component.

Kemudian buat method render yang mereturn tag Component widget seperti View , Text , maupun Image , atau yang lainnya yang Anda bisa dapatkan dari modul React Native.

Sekarang saatnya kita praktekkan.

Pertama, buat sebuah project React Native bernama "FunctionalComponent":

react-native init ClassBasedComponent

Kemudian, tunggu beberapa saat hingga React Native selesai menggenerate project.

Selanjutnya, setelah proses itu selesai, buka file "App.js".

Kemudian replace isinya menjadi seperti ini:

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

class App extends Component{
	render(){
		return <Text>Hello World!</Text>;
	}
}

export default App;

Kemudian jalankan emulator Android, lalu jalankan program ini dengan perintah:

react-native run-android

Nanti tampilannya akan seperti ini:

Dari kedua contoh tadi, kita bisa lihat bahwa hasil yang didapatkan pada emulator adalah sama.

Bedanya pada Functional Component, tag JSX dimasukkan ke dalam return value dari fungsi utama, sedangkan pada Class Based Component, tag JSX dimasukkan ke dalam method render .

Walaupun begitu, Class Based Component memiliki fitur yang lebih banyak daripada Functional Component karena memiliki akses ke state dan lifecycle method yang memungkinkan untuk membuat Component yang dinamis.

Selain itu, pada contoh tadi, kita langsung membuat Component di App, yang merupakan Component utama karena App didaftarkan dalam AppRegistry .

Kita juga bisa membuat Component tambahan sehingga aplikasi React Native kita terdiri dari banyak Component.

Mengexport dan Mengimport Component

Jika Anda perhatikan pada kedua kode tadi, ada baris kode seperti ini:

export default App;

Ini adalah kode untuk mengekspor Component.

Setelah pemasangan kode tersebut, Component dapat diimport dengan cara ini:

import App from "./App";

Bagian ./App tentunya tergantung lokasi App relatif terhadap pengimport.

Sehingga untuk mengimport App dari folder yang sama dilakukan dengan cara tadi.

Namun, apabila App berada pada suatu subfolder, katakanlah "src", maka kode pengimportnya akan seperti ini:

import App from "./src/App"

Dan perlu diingat juga karena App berekstensi .js, maka ".js" tidak perlu disertakan saat mengimportnya.

Cara Lain untuk Mengexport dan Mengimport Component

Walaupun cara sebelumnya cukup sederhana untuk mengexport dan mengimport Component, sebenarnya masih ada lagi cara yang lebih rumit tapi sangat praktis.

Prinsipnya adalah dengan menempatkan Component - Component dalam sebuah folder.

Kemudian dengan sintaks export khusus, kita mengexport setiap Component yang ada di folder tersebut.

Selanjutnya, kita buat sebuah file index yang digunakan untuk memetakan Component-Component yang diexport dalam folder tersebut.

Kemudian untuk mengimportnya, kita tidak mengimport filenya secara individual, melainkan dengan mengimport file index tadi.

Dengan cara ini kita bisa mengambil sebagian atau seluruh Component yang ada dalam folder tadi.

Sekarang kita praktekkan cara itu.

Buatlah sebuah project React Native bernama "EximSekaligus":

react-native init EximSekaligus

Kemudian tunggu hingga project selesai dibuat.

Setelah project selesai dibuat, buat folder baru di dalam folder "EximSekaligus" dengan nama "common".

Kemudian buat file baru di dalamnya:

  • Welcome.js
  • NamaToko.js
  • AlamatToko.js
  • index.js

Berikut ini isi dari file Welcome.js:

import React from "react";
import { Text } from "react-native";

const Welcome = () => {
  return <Text>Welcome!</Text>;
};

export { Welcome };

Berikut ini isi dari file NamaToko.js:

import React from "react";
import { Text } from "react-native";

const NamaToko = () => {
  return <Text>Ini adalah toko jam tangan!</Text>;
};

export { NamaToko };

Berikut ini isi dari file AlamatToko.js:

import React from "react";
import { Text } from "react-native";

const AlamatToko = () => {
  return <Text>Kunjungi Toko Ini di Jalan Duren No. 44</Text>;
};

export { AlamatToko };

Berikut ini isi dari file index.js:

export * from "./Welcome";
export * from "./NamaToko";
export * from "./AlamatToko";

Selanjutnya, buka file App.js dari folder "EximSekaligus" dan ubah isinya menjadi seperti ini:

import React from 'react';
import {View} from 'react-native';
import { Welcome, NamaToko, AlamatToko } from "./common";

const App = () => {
	return (
		<View>
			<Welcome/>
			<NamaToko/>
			<AlamatToko/>
		</View>
	);
};

export default App;

Kemudian jalankan emulator dan jalankan aplikasinya dengan:

react-native run-android

Nanti tampilannya akan seperti ini:

Tampak bahwa dengan mengimport folder common seperti ini:

import { Welcome, NamaToko, AlamatToko } from "./common";

Kita bisa menggunakan Component-Component yang diexport dengan cara ini:

export { NamaComponent }; //Nama Component: Welcome, NamaToko, AlamatToko

Tapi tentunya dengan perantara file index.js ini:

export * from "./Welcome";
export * from "./NamaToko";
export * from "./AlamatToko";

Sehingga kita bisa mengambil sebagian atau seluruh Component yang diexport dengan cara tadi dan menggunakannya dalam App.js:

return (
		<View>
			<Welcome/>
			<NamaToko/>
			<AlamatToko/>
		</View>
	);

Cara ini sangat berguna ketika kita memiliki Component yang reusable, karena dengan cara ini kita bisa membuat Component yang akan digunakan dimanapun dengan mudah.

Namun ingat, bahwa jika Component tadi memiliki dependency di luar folder Componentnya, maka dependency tersebut juga harus disertakan.

Props dan Style

Dalam membangun Component, ada kalanya kita ingin memberikan argument pada Component tersebut.

Misalnya, Anda membuat sebuah tombol.

Lalu Anda ingin bisa memberi konfigurasi pada tombol tersebut entah itu ukurannya besar atau kecil, atau warnanya merah atau biru.

Untuk tujuan tersebut, React Native memiliki fitur Props.

Dengan fitur tersebut, tag JSX dari Component bisa diberi parameter semacam ini:

<Tombol size="big"/>

Props ini bisa digunakan baik pada Functional Component maupun Class Based Component.

Selain itu, kita telah lihat bahwa tampilan Component yang telah kita buat sebelumnya tampak terlalu plain.

Tidak bergaya.

Untuk memberi gaya pada tampilan Component, React Native memiliki fitur Style.

Fitur Style ini cara kerjanya seperti CSS kalau di web app.

Bahkan sintaksnya pun serupa, tapi bukannya dengan menggunakan strip (-), tapi menggunakan camelCase.

Sekarang saatnya kita mempraktekkan ini.

Buatlah sebuah project React Native baru bernama "PropsDemo":

react-native init PropsDemo

Setelah project selesai dibuat, buat folder baru dalam folder "PropsDemo" dengan nama "components".

Kemudian buat 2 file baru di dalamnya:

  • FunctionalTombol.js
  • ClassBasedTombol.js

Isi dari FunctionalTombol.js adalah seperti ini:

import React from "react";
import { Text, TouchableOpacity } from "react-native";

const FunctionalTombol = (props) => {
  const { buttonStyle, textStyle } = styles;
  return (
    <TouchableOpacity onPress={props.onPress} style={buttonStyle}>
      <Text style={textStyle}>{props.children}</Text>
    </TouchableOpacity>
  );
};

const styles = {
  textStyle: {
    alignSelf: "center",
    color: "#007aff",
    fontSize: 16,
    fontWeight: "600",
    paddingTop: 10,
    paddingBottom: 10
  },
  buttonStyle: {
    flex: 1,
    alignSelf: "stretch",
    backgroundColor: "#fff",
    borderRadius: 5,
    borderWidth: 1,
    borderColor: "#007aff",
    marginLeft: 5,
    marginRight: 5
  }
};

export default FunctionalTombol;

Sedangkan isi dari ClassBasedTombol.js adalah seperti ini:

import React, { Component } from "react";
import { Text, TouchableOpacity } from "react-native";

class ClassBasedTombol extends Component{
	render(){
		const { buttonStyle, textStyle } = styles;
		return (
			<TouchableOpacity onPress={this.props.onPress} style={buttonStyle}>
				<Text style={textStyle}>{this.props.children}</Text>
			</TouchableOpacity>
		);
	}
}

const styles = {
  textStyle: {
    alignSelf: "center",
    color: "#007aff",
    fontSize: 16,
    fontWeight: "600",
    paddingTop: 10,
    paddingBottom: 10
  },
  buttonStyle: {
    flex: 1,
    alignSelf: "stretch",
    backgroundColor: "#fff",
    borderRadius: 5,
    borderWidth: 1,
    borderColor: "#007aff",
    marginLeft: 5,
    marginRight: 5
  }
};

export default ClassBasedTombol;

Sekarang, ubah "PropsDemo/App.js" menjadi seperti ini:

import React from 'react';
import {View, Alert} from 'react-native';
import FunctionalTombol from "./components/FunctionalTombol";
import ClassBasedTombol from "./components/ClassBasedTombol";

const App = () => {
	return (
		<View style={styles.containerStyle}>
			<FunctionalTombol onPress={() => {Alert.alert('FunctionalTombol','Tombol ditekan!');}}>Ini Functional Tombol</FunctionalTombol>
			<ClassBasedTombol onPress={() => {Alert.alert('ClassBasedTombol','Tombol ditekan!');}}>Ini ClassBased Tombol</ClassBasedTombol>
		</View>
	);
};

const styles = {
  containerStyle: {
    borderBottomWidth: 1,
    padding: 5,
    backgroundColor: "#fff",
    justifyContent: "flex-start",
    flexDirection: "row",
    borderColor: "#ddd",
    position: "relative"
  }
};

export default App;

Kemudian, jalankan project ini:

react-native run-android

Nanti tampilannya seperti ini:

Ketika tombol-tombol tersebut diklik, akan muncul Alert .

Penjelasannya begini...

Pada FunctionalTombol.js, kita mendefinisikan layout dari tombol:

import React from "react";
import { Text, TouchableOpacity } from "react-native";

const FunctionalTombol = (props) => {
  const { buttonStyle, textStyle } = styles;
  return (
    <TouchableOpacity onPress={props.onPress} style={buttonStyle}>
      <Text style={textStyle}>{props.children}</Text>
    </TouchableOpacity>
  );
};

Tombol tersebut bisa menerima argument dari pemanggillnya melalui variable props ini:

(props) => {

Jadi props tadi mengalir dari parent component ini (di App.js):

<FunctionalTombol onPress={() => {Alert.alert('FunctionalTombol','Tombol ditekan!');}}>Ini
Functional Tombol</FunctionalTombol>

Tepatnya pada bagian onPress .

Kemudian dilanjutkan dengan penerimaan onPress pada Functional Tombol:

onPress={props.onPress}

Sedemikian rupa sehingga TouchableOpacity yang dapat menghandle onPress memahami bagaimana kelanjutannya ketika Functional Tombol ditekan.

Dalam hal ini, lakukan alert:

Alert.alert('FunctionalTombol','Tombol ditekan!');

Hal ini serupa dengan Class Based Tombol, bedanya ia ada di method render karena merupakan Class Based Component:

render(){
		const { buttonStyle, textStyle } = styles;
		return (
			<TouchableOpacity onPress={this.props.onPress} style={buttonStyle}>
				<Text style={textStyle}>{this.props.children}</Text>
			</TouchableOpacity>
		);
	}

Selain itu, pada Class Based Tombol, props didapatkan melalui this :

this.props.onPress

Adapun this.props.children didapatkan untuk mendapatkan nilai antara opening dan closing tags:

<ClassBasedTombol onPress={() => {Alert.alert('ClassBasedTombol','Tombol ditekan!');}}>Ini
ClassBased Tombol</ClassBasedTombol>

Terakhir, style didefinisikan pada kedua tombol tersebut:

const styles = {
  textStyle: {
    alignSelf: "center",
    color: "#007aff",
    fontSize: 16,
    fontWeight: "600",
    paddingTop: 10,
    paddingBottom: 10
  },
  buttonStyle: {
    flex: 1,
    alignSelf: "stretch",
    backgroundColor: "#fff",
    borderRadius: 5,
    borderWidth: 1,
    borderColor: "#007aff",
    marginLeft: 5,
    marginRight: 5
  }
};

Kemudian diapply pada masing-masing tombol:

style={buttonStyle}
style={textStyle}

Untuk memahami seluruh makna styling di React Native, kunjungi dokumentasi untuk masing-masing Component di:

https://facebook.github.io/react-native/docs/getting-started

Tepatnya di bagian Components > Style.

State

Dalam membuat Component, ada kalanya kita ingin agar data yang dipegang oleh Component bisa berubahubah atau dinamis.

Untuk keperluan itu, React Native memiliki fitur yang disebut dengan State.

State adalah sebuah variabel bawaan yang dimiliki oleh Class Based Component yang nilainya dapat berubah-ubah.

Perlu ditekankan di sini bahwa hanya Class Based Component saja yang memiliki State, Functional Component tidak walaupun keduanya sama-sama memiliki Props.

Jadi, kuncinya ketika kita ingin membuat Component dinamis, gunakan Class Based Component dan jika ingin membuat Component statis, gunakan Functional Component.

Sekarang saatnya kita mempraktekkan ini.

Buatlah sebuah project React Native baru bernama "StateDemo":

react-native init StateDemo

Setelah project selesai dibuat, ubah "App.js" menjadi seperti ini:

import React, { Component } from "react";
import { Text, TextInput, View } from "react-native";

class App extends Component {
  state = { nama: "" };

  render() {
    return (
      <View>
        <TextInput
          onChangeText={text => {
            this.setState({ nama: text });
          }}
        />
        <Text>Inilah nama saya: {this.state.nama}</Text>
      </View>
    );
  }
}

export default App;

Selanjutnya, jalankan emulator kemudian jalankan aplikasi ini:

react-native run-android

Nanti tampilannya seperti ini:

Di sana Anda bisa mengetikkan input teks dan outputnya akan ditampilkan di elemen teks di bawahnya.

Contohnya, saya mengetikkan "Pus Galak" di TextInput , kemudian hasilnya "Saya adalah Pus Galak" di Text di bawahnya.

Penjelasannya begini...

Pertama-tama, saya membuat Component bernama App . Ini adalah Component utama:

class App extends Component {
  state = { nama: "" };

  render() {
    return (
      <View>
        <TextInput
          onChangeText={text => {
            this.setState({ nama: text });
          }}
        />
        <Text>Inilah nama saya: {this.state.nama}</Text>
      </View>
    );
  }
}

Kemudian, saya mendefinisikan state di Component tersebut:

state = { nama: "" };

Saat ini state berisi variable nama yang isinya masih kosong.

Kemudian, pada sub Component TextInput, saya ingin agar setiap kali kita mengetikkan input, maka state akan berubah sesuai inputnya:

<TextInput
onChangeText={text => {
this.setState({ nama: text });
}}
/>

Caranya dengan mengisi event onChangeText dengan callback ini:

text => {
this.setState({ nama: text });
}

Karena setState dipanggil, maka isi state nama tadi berubah, dan efeknya ada pada sub Component Text di bawahnya:

<Text>Inilah nama saya: {this.state.nama}</Text>

Dari sini bisa kita lihat bahwa saat state diubah, Component akan dirender ulang, karena seiring kita mengisi input, maka "Saya adalah..." juga berubah.

Untuk membaca bab-bab studi kasus tutorial ini, baca ebook "Javascript for Everything" ini.