Lewati ke konten
Kembali ke Blog

Cara Membuat Aplikasi Mobile dengan React Native

· · 7 menit baca

React Native memungkinkan membuat aplikasi mobile untuk Android dan iOS dengan JavaScript. Mari pelajari dari dasar.

Setup Environment

Prerequisites

# Install Node.js (18+)
# Download dari nodejs.org

node --version npm --version

Install React Native CLI

# Install Expo CLI (recommended untuk pemula)
npm install -g expo-cli

Atau React Native CLI (untuk native modules)

npm install -g react-native-cli

Android Setup

# Install Android Studio
# Download dari developer.android.com

Set environment variables (Linux/Mac)

export ANDROID_HOME=$HOME/Android/Sdk export PATH=$PATH:$ANDROID_HOME/emulator export PATH=$PATH:$ANDROID_HOME/platform-tools

Verify

adb --version

Create New Project

With Expo

# Create project
npx create-expo-app MyApp
cd MyApp

Start development

npx expo start

Run on device

- Scan QR code dengan Expo Go app

- Atau tekan 'a' untuk Android emulator

- Atau tekan 'i' untuk iOS simulator

With React Native CLI

# Create project
npx react-native init MyApp
cd MyApp

Run on Android

npx react-native run-android

Run on iOS

npx react-native run-ios

Basic Components

View dan Text

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

export default function App() { return ( <View style={styles.container}> <Text style={styles.title}>Hello React Native!</Text> <Text style={styles.subtitle}>Ini adalah aplikasi pertama saya</Text> </View> ); }

const styles = StyleSheet.create({ container: { flex: 1, justifyContent: "center", alignItems: "center", backgroundColor: "#f5f5f5", }, title: { fontSize: 24, fontWeight: "bold", color: "#333", }, subtitle: { fontSize: 16, color: "#666", marginTop: 10, }, });

Button dan TouchableOpacity

import { Button, TouchableOpacity, Alert } from "react-native";

function MyComponent() { const handlePress = () => { Alert.alert("Halo!", "Button ditekan"); };

return ( <View> {/ Basic Button /} <Button title="Tekan Saya" onPress={handlePress} color="#007AFF" />

  {/* Custom Button dengan TouchableOpacity */}
  &lt;TouchableOpacity
    style={styles.customButton}
    onPress={handlePress}
    activeOpacity={0.7}
  &gt;
    &lt;Text style={styles.buttonText}&gt;Custom Button&lt;/Text&gt;
  &lt;/TouchableOpacity&gt;
&lt;/View&gt;

);
}

Image

import { Image } from "react-native";

function MyComponent() { return ( <View> {/ Local image /} <Image source={require("./assets/logo.png")} style={{ width: 100, height: 100 }} />

  {/* Remote image */}
  &lt;Image
    source={{ uri: &quot;https://example.com/image.png&quot; }}
    style={{ width: 200, height: 200 }}
    resizeMode=&quot;cover&quot;
  /&gt;
&lt;/View&gt;

);
}

Input dan Forms

TextInput

import { TextInput } from "react-native";
import { useState } from "react";

function LoginForm() { const [email, setEmail] = useState(""); const [password, setPassword] = useState("");

return ( <View style={styles.form}> <TextInput style={styles.input} placeholder="Email" value={email} onChangeText={setEmail} keyboardType="email-address" autoCapitalize="none" />

  &lt;TextInput
    style={styles.input}
    placeholder=&quot;Password&quot;
    value={password}
    onChangeText={setPassword}
    secureTextEntry={true}
  /&gt;

  &lt;Button title=&quot;Login&quot; onPress={() =&gt; console.log(email, password)} /&gt;
&lt;/View&gt;

);
}

const styles = StyleSheet.create({
form: {
padding: 20,
},
input: {
borderWidth: 1,
borderColor: "#ddd",
padding: 15,
marginBottom: 15,
borderRadius: 8,
fontSize: 16,
},
});

Lists

FlatList

import { FlatList } from "react-native";

function TodoList() { const todos = [ { id: "1", title: "Belajar React Native" }, { id: "2", title: "Buat aplikasi pertama" }, { id: "3", title: "Deploy ke Play Store" }, ];

const renderItem = ({ item }) => ( <View style={styles.todoItem}> <Text>{item.title}</Text> </View> );

return ( <FlatList data={todos} renderItem={renderItem} keyExtractor={(item) => item.id} ItemSeparatorComponent={() => <View style={styles.separator} />} /> ); }

ScrollView

import { ScrollView } from "react-native";

function LongContent() { return ( <ScrollView style={styles.container} showsVerticalScrollIndicator={false}> <Text style={styles.paragraph}>Paragraf 1...</Text> <Text style={styles.paragraph}>Paragraf 2...</Text> <Text style={styles.paragraph}>Paragraf 3...</Text> {/ More content /} </ScrollView> ); }

Navigation

Install React Navigation

# Install core
npm install @react-navigation/native

Install dependencies

npx expo install react-native-screens react-native-safe-area-context

Install stack navigator

npm install @react-navigation/native-stack

Stack Navigation

import { NavigationContainer } from "@react-navigation/native";
import { createNativeStackNavigator } from "@react-navigation/native-stack";

const Stack = createNativeStackNavigator();

function HomeScreen({ navigation }) { return ( <View style={styles.container}> <Text>Home Screen</Text> <Button title="Go to Details" onPress={() => navigation.navigate("Details", { itemId: 123 })} /> </View> ); }

function DetailsScreen({ route, navigation }) { const { itemId } = route.params;

return ( <View style={styles.container}> <Text>Details Screen</Text> <Text>Item ID: {itemId}</Text> <Button title="Go Back" onPress={() => navigation.goBack()} /> </View> ); }

export default function App() { return ( <NavigationContainer> <Stack.Navigator initialRouteName="Home"> <Stack.Screen name="Home" component={HomeScreen} /> <Stack.Screen name="Details" component={DetailsScreen} /> </Stack.Navigator> </NavigationContainer> ); }

Tab Navigation

import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
import { Ionicons } from "@expo/vector-icons";

const Tab = createBottomTabNavigator();

export default function App() { return ( <NavigationContainer> <Tab.Navigator screenOptions={({ route }) => ({ tabBarIcon: ({ focused, color, size }) => { let iconName; if (route.name === "Home") { iconName = focused ? "home" : "home-outline"; } else if (route.name === "Profile") { iconName = focused ? "person" : "person-outline"; } return <Ionicons name={iconName} size={size} color={color} />; }, })} > <Tab.Screen name="Home" component={HomeScreen} /> <Tab.Screen name="Profile" component={ProfileScreen} /> </Tab.Navigator> </NavigationContainer> ); }

State Management

useState

import { useState } from "react";

function Counter() { const [count, setCount] = useState(0);

return ( <View style={styles.container}> <Text style={styles.count}>{count}</Text> <View style={styles.buttons}> <Button title="-" onPress={() => setCount(count - 1)} /> <Button title="+" onPress={() => setCount(count + 1)} /> </View> </View> ); }

useEffect

import { useState, useEffect } from "react";

function DataFetcher() { const [data, setData] = useState(null); const [loading, setLoading] = useState(true);

useEffect(() => { fetch("https://api.example.com/data") .then((response) => response.json()) .then((json) => { setData(json); setLoading(false); }) .catch((error) => { console.error(error); setLoading(false); }); }, []);

if (loading) { return <ActivityIndicator size="large" />; }

return ( <View> <Text>{JSON.stringify(data)}</Text> </View> ); }

Styling

Flexbox Layout

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: "row", // 'column' default
    justifyContent: "space-between",
    alignItems: "center",
    padding: 20,
  },
  box: {
    width: 100,
    height: 100,
    backgroundColor: "#007AFF",
  },
});

Responsive Design

import { Dimensions, useWindowDimensions } from "react-native";

function ResponsiveComponent() { const { width, height } = useWindowDimensions(); const isLandscape = width > height;

return ( <View style={[ styles.container, { flexDirection: isLandscape ? "row" : "column" }, ]} > <Text>Width: {width}</Text> <Text>Height: {height}</Text> </View> ); }

API Integration

Fetch Data

const fetchUsers = async () => {
  try {
    const response = await fetch("https://jsonplaceholder.typicode.com/users");
    const data = await response.json();
    return data;
  } catch (error) {
    console.error("Error fetching users:", error);
    throw error;
  }
};

// POST request const createUser = async (userData) => { try { const response = await fetch("https://api.example.com/users", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify(userData), }); return await response.json(); } catch (error) { console.error("Error creating user:", error); throw error; } };

Build dan Deploy

Build APK (Android)

# Expo
npx expo build:android

EAS Build (recommended)

npm install -g eas-cli eas build -p android

React Native CLI

cd android ./gradlew assembleRelease

Build iOS

# Expo
npx expo build:ios

EAS Build

eas build -p ios

Note: iOS requires Apple Developer account ($99/year)

Kesimpulan

React Native adalah cara efisien untuk membuat aplikasi mobile cross-platform. Mulai dengan Expo untuk development lebih mudah, lalu migrate ke bare workflow jika butuh native modules.

Ditulis oleh

Hendra Wijaya

Tinggalkan Komentar

Email tidak akan ditampilkan.