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.
-
useAuth → custom 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:
-
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:
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
-
Tampilan awal login
-
Validasi form kosong
-
Login dengan akun tidak terdaftar
-
Login sukses (akan diarahkan ke dashboard, yang nanti kita buat)