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.
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.
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.
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
AuthProvideragar semua halaman bisa menggunakan context yang telah kita buat. - kita memanggil sebuah halaman
loginmenggunakanStack.Screendan menyembunyikan header-nya menggunakan optionsheaderShown: 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.
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.
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:
const { user, isLoading } = useAuth();
userberisi data pengguna yang sedang login (ataunulljika belum login)isLoadingmenandakan apakah aplikasi masih dalam proses memeriksa status autentikasi
Kemudian, kita panggil state isLoading untuk menampilkan loading spinner saat state isLoading === true.
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.
{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.tsxapp/(auth)/register.tsx(untuk nanti, masih kosong)
¶Kode Login
Buka file login.tsx, lalu masukkan kode berikut:
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:
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.
- useAuth → custom hook dari Auth Context yang berisi fungsi
handleLogin. - router → utilitas dari
expo-routeruntuk 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.
// call useAuth hooks
const { handleLogin } = useAuth();
Lalu kita buat tiga state:
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:
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:
- Validasi → Jika email/password kosong, tampilkan alert.
- Proses Login → Aktifkan loading, lalu panggil
handleLogin. - Tangkap Error → Jika gagal login, tampilkan pesan error.
- Reset Loading → Matikan loading setelah proses selesai.
Bagian return membangun UI halaman login:
<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
secureTextEntryagar karakter disembunyikan. - Button Masuk → memanggil
handleAuth. - Button Daftar → navigasi ke
/(auth)/register.
¶Screenshoot Hasil
- Tampilan awal login

- Validasi form kosong

- Login dengan akun tidak terdaftar

- Login sukses (akan diarahkan ke dashboard, yang nanti kita buat)
