Menu
📱 Lihat versi lengkap (non-AMP)
Programming Mobile Development

Cara Membuat Aplikasi Mobile dengan React Native

Editor: Hendra WIjaya
Update: 7 January 2026
Baca: 5 menit

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

# Verify installation
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 */}
      <TouchableOpacity
        style={styles.customButton}
        onPress={handlePress}
        activeOpacity={0.7}
      >
        <Text style={styles.buttonText}>Custom Button</Text>
      </TouchableOpacity>
    </View>
  );
}

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 */}
      <Image
        source={{ uri: "https://example.com/image.png" }}
        style={{ width: 200, height: 200 }}
        resizeMode="cover"
      />
    </View>
  );
}

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"
      />

      <TextInput
        style={styles.input}
        placeholder="Password"
        value={password}
        onChangeText={setPassword}
        secureTextEntry={true}
      />

      <Button title="Login" onPress={() => console.log(email, password)} />
    </View>
  );
}

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>
  );
}

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.

Artikel Terkait

Bagikan:

Link Postingan: https://www.tirinfo.com/cara-membuat-aplikasi-react-native/