Tutorial React Native Auth - #5 - Membuat Login Screen React Native

Artikel ini merupakan series dari Tutorial Authentication Dengan React Native dan Laravel Sanctum, disini kita akan membuat sebuah login screen pada project kita

Rafi Taufiqurrahman
Dipublish 09/08/2025

Pada artikel kali ini kita akan membuat sebuah screen login untuk aplikasi kita , tapi sebelum itu kita akan membungkus seluruh aplikasi kita menggunakan AuthProvider yang telah kita buat sebelumnya.

Membungkus Aplikasi dengan AuthProvider

silahkan teman - teman buka file yang bernama _layout.tsx yang terletak didalam folder app dan masukan kode berikut ini.

_layout.tsx
import { AuthProvider } from "@/context/AuthContext";
import { Stack } from "expo-router";

export default function RootLayout() {
    return (
        <AuthProvider>
            <Stack>
                <Stack.Screen name='(auth)/login' options={{ headerShown: false }}/>
            </Stack>
        </AuthProvider>
    )
}

Pada kode diatas, pertama - tama kita import beberapa file yang kita butuhkan.

_layout.tsx
import { AuthProvider } from "@/context/AuthContext";
import { Stack } from "expo-router";

Kemudian, didalam React Functional Component kita memanggil sebuah context AuthProvider yang kita buat sebelumnya dan Stack dari expo-router.

_layout.tsx
export default function RootLayout() {
  return (
      <AuthProvider>
          <Stack>
              <Stack.Screen name='(auth)/login' options={{ headerShown: false }}/>
          </Stack>
      </AuthProvider>
  )
}

Pada kode diatas:

  • kita membungkus seluruh apilkasi dengan AuthProvider agar semua halaman bisa menggunakan context yang telah kita buat.
  • kita memanggil sebuah halaman login menggunakan Stack.Screen dan menyembunyikan header-nya menggunakan options headerShown: false.

Redirect Otomatis Berdasarkan Status Login

Setelah kita pasang AuthProvider, selanjutnya kita akan menentukan routing logic saat aplikasi pertama kali dibuka. Apakah user langsung diarahkan ke halaman dashboard atau harus login terlebih dahulu, untuk itu silahkan teman - teman buka file yang bernama index.tsx yang terletak didalam folder app, kemudian masukan kode berikut ini.

index.tsx
import { useAuth } from '@/hooks/useAuth';
import { Redirect } from 'expo-router';
import React from 'react';
import { ActivityIndicator, View } from 'react-native';

export default function Index() {
    const { user, isLoading } = useAuth();

    if (isLoading) {
      return (
        <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
          <ActivityIndicator size="large" color="#007AFF" />
        </View>
      );
    }

    return (
      <>
        {user ? <Redirect href="/(home)/dashboard" /> : <Redirect href="/(auth)/login" />}
      </>
    );
}

Pada kode diatas, pertama - tama kita import beberapa file yang kita butuhkan.

index.tsx
import { useAuth } from '@/hooks/useAuth';
import { Redirect } from 'expo-router';
import React from 'react';
import { ActivityIndicator, View } from 'react-native';

Setelah itu, kita panggil custom hook useAuth yang sebelumnya udah kita buat. Dari situ, kita ambil beberapa state yang udah kita definisikan di dalam context, yaitu user dan isLoading:

index.tsx
const { user, isLoading } = useAuth();
  • user berisi data pengguna yang sedang login (atau null jika belum login)
  • isLoading menandakan apakah aplikasi masih dalam proses memeriksa status autentikasi

Kemudian, kita panggil state isLoading untuk menampilkan loading spinner saat state isLoading === true.

index.tsx
if (isLoading) {
  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <ActivityIndicator size="large" color="#007AFF" />
    </View>
  );
}

Terkahir kita lakukan pengecekan state user, jika bernilai true kita akan arahkan user kehalaman dashboard jika false akan kita arahkan ke halaman login.

index.tsx
{user ? <Redirect href="/(home)/dashboard" /> : <Redirect href="/(auth)/login" />}

Membuat Screen Login

Setelah kita memasang AuthProvider dan membuat logika redirect otomatis di index.tsx, sekarang saatnya membuat screen login yang akan menjadi pintu masuk utama pengguna ke aplikasi.

Struktur Folder

Silakan teman–teman buat folder baru bernama (auth) di dalam folder app, lalu di dalamnya buat dua file:

  • app/(auth)/login.tsx
  • app/(auth)/register.tsx (untuk nanti, masih kosong)

Kode Login

Buka file login.tsx, lalu masukkan kode berikut:

login.tsx
import { Button } from "@/components/button";
import { Input } from "@/components/input";
import { useAuth } from "@/hooks/useAuth";
import { router } from "expo-router";
import { useState } from "react";
import { Alert, StyleSheet, Text, View } from "react-native";

export default function Login() {
    // call useAuth hooks
    const { handleLogin } = useAuth();

    // define state email
    const [email, setEmail] = useState('');
    
    // define state password
    const [password, setPassword] = useState('');

    // define state loading
    const [loading, setLoading] = useState(false);

    // define method handleAuth
    const handleAuth = async () => {
      if (!email || !password) {
        Alert.alert("Validasi", "Email dan password harus diisi");
        return;
      }

      try{
        setLoading(true);
        await handleLogin(email, password);
      }catch(error: any){
        Alert.alert('Login Gagal', error.response?.data?.message || 'Terjadi kesalahan');
      }finally{
        setLoading(false);
      }
    }
    return (
      <View style={styles.container}>
        <Text style={styles.title}>Login</Text>
          <View>
            <Text style={styles.label}>Email</Text>
              <Input
                placeholder="email@example.com"
                keyboardType="email-address"
                autoCapitalize="none"
                value={email}
                onChangeText={setEmail}
              />
          </View>
          <View>
              <Text style={styles.label}>Kata Sandi</Text>
              <Input
                placeholder="********"
                secureTextEntry
                value={password}
                onChangeText={setPassword}
              />
          </View>
        <Button title="Masuk" disabled={loading} onPress={handleAuth}/>
        <Button title="Daftar" variant='dark' onPress={() => router.push('/(auth)/register')}/>
      </View>
    );
}

const styles = StyleSheet.create({
    container: {
      flex: 1,
      justifyContent: "center",
      paddingHorizontal: 32,
      backgroundColor: "#fff",
    },
    title: {
      fontSize: 32,
      fontWeight: "bold",
      marginBottom: 32,
      textAlign: "center",
    },
    label : {
      marginBottom: 4,
    }
});

Penjelasan Kode

Pertama, kita import semua file dan modul yang diperlukan:

login.tsx
import { Button } from "@/components/button";
import { Input } from "@/components/input";
import { useAuth } from "@/hooks/useAuth";
import { router } from "expo-router";
import { useState } from "react";
import { Alert, StyleSheet, Text, View } from "react-native";
  • Button & Input → komponen kustom untuk tombol dan kolom input.
  • useAuthcustom hook dari Auth Context yang berisi fungsi handleLogin.
  • router → utilitas dari expo-router untuk navigasi antar halaman.
  • useState → hook React untuk mengelola state lokal.
  • Alert, StyleSheet, Text, View → komponen bawaan React Native.

Di dalam React Functional Component Login, kita ambil fungsi handleLogin dari AuthContext.

login.tsx
// call useAuth hooks
const { handleLogin } = useAuth();

Lalu kita buat tiga state:

login.tsx
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [loading, setLoading] = useState(false);
  • email → menyimpan input alamat email.
  • password → menyimpan input kata sandi.
  • loading → menandai proses login sedang berjalan.

Selanjutnya kita buat fungsi handleAuth yang akan dieksekusi saat tombol Masuk ditekan:

login.tsx
const handleAuth = async () => {
  if (!email || !password) {
    Alert.alert("Validasi", "Email dan password harus diisi");
    return;
  }

  try{
    setLoading(true);
    await handleLogin(email, password);
  }catch(error: any){
    Alert.alert('Login Gagal', error.response?.data?.message || 'Terjadi kesalahan');
  }finally{
    setLoading(false);
  }
}

Alurnya:

  1. Validasi → Jika email/password kosong, tampilkan alert.
  2. Proses Login → Aktifkan loading, lalu panggil handleLogin.
  3. Tangkap Error → Jika gagal login, tampilkan pesan error.
  4. Reset Loading → Matikan loading setelah proses selesai.

Bagian return membangun UI halaman login:

login.tsx
<View style={styles.container}>
  <Text style={styles.title}>Login</Text>

  <View>
    <Text style={styles.label}>Email</Text>
    <Input
      placeholder="email@example.com"
      keyboardType="email-address"
      autoCapitalize="none"
      value={email}
      onChangeText={setEmail}
    />
  </View>

  <View>
    <Text style={styles.label}>Kata Sandi</Text>
    <Input
      placeholder="********"
      secureTextEntry
      value={password}
      onChangeText={setPassword}
    />
  </View>

  <Button title="Masuk" disabled={loading} onPress={handleAuth}/>
  <Button title="Daftar" variant='dark' onPress={() => router.push('/(auth)/register')}/>
</View>
  • Input Email → dengan keyboardType="email-address" agar keyboard sesuai.
  • Input Password → dengan secureTextEntry agar karakter disembunyikan.
  • Button Masuk → memanggil handleAuth.
  • Button Daftar → navigasi ke /(auth)/register.

Screenshoot Hasil

  1. Tampilan awal login login-screen
  2. Validasi form kosong validation
  3. Login dengan akun tidak terdaftar fresh-project
  4. Login sukses (akan diarahkan ke dashboard, yang nanti kita buat) fresh-project

Artikel Lainnya

Beberapa artikel rekomendasi lainnya untuk menambah pengetahuan.

1
Tutorial Laravel Rest API - #3 - Membuat Module Register
Artikel ini merupakan series dari Tutorial Authentication Dengan Laravel Sanctum dan Unit Testing, disini kita belajar membuat module registrasi selain membuat rest api kita juga menuliskan sebuah unit test untuk module tersebut.
2
Tutorial Laravel Livewire - #4 - Membuat Schema Database Dengan Laravel
Artikel ini merupakan series dari Tutorial Laravel Livewire Study Case Point Of Sales, disini kita akan membuat sebuah schema database yang nantinya akan kita gunakan pada study case kali ini dan kita akan memanfaatkan model dan migration dari laravel.
3
Tutorial Inertia Roles & Permissions - #3 - Installasi Laravel Breeze & Inertia
Artikel ini merupakan series dari Tutorial Laravel Inertia Roles & Permissions, disini kita akan melakukan installasi laravel breeze dan inertia sebagai starter-kit kita.
4
Tutorial Laravel Livewire - #9 - Membuat Module Product Dengan Livewire
Artikel ini merupakan series dari Tutorial Laravel Livewire Study Case Point Of Sales, disini kita akan membuat sebuah module product dengan livewire.
5
Tutorial Inertia Roles & Permissions - #9 - Membuat Utils Permissions Dengan Inertia React
Artikel ini merupakan series dari Tutorial Laravel Inertia Roles & Permissions, disini kita akan belajar membuat sebuah utils untuk menghandle permissions yang kita miliki.
6
Tutorial Laravel Livewire - #10 - Membuat Module POS Dengan Livewire
Artikel ini merupakan series dari Tutorial Laravel Livewire Study Case Point Of Sales, disini kita akan membuat sebuah module pos dengan livewire.

JurnalKoding

Mulai asah skill dengan berbagai macam teknologi - teknologi terbaru seperti Laravel, React, Vue, Inertia, Tailwind CSS, dan masih banyak lagi.

© 2025 JurnalKoding, Inc. All rights reserved.