React Native Expo ile E-Ticaret Uygulaması Geliştirme: Adım Adım Detaylı Anlatım
Bu makalede, React Native Expo kullanarak bir e-ticaret uygulamasının nasıl geliştirildiğini adım adım anlatacağım. Projenin her aşamasını, kullanılan teknolojileri, kodların neden bu şekilde yazıldığını ve nasıl çalıştığını detaylı bir şekilde açıklayacağım. Bu makalenin sonunda github profilimden tüm projeye erişim sağlayabilirsiniz.
1. Projenin Amacı ve Kullanılan Teknolojiler
Projenin Amacı
Bu proje, kullanıcıların ürünleri listeleyebileceği, detaylarını inceleyebileceği, sepete ekleyebileceği ve favorilere ekleyebileceği bir mobil e-ticaret uygulaması geliştirmeyi amaçlamaktadır. Proje, kullanıcı dostu bir arayüz, performanslı bir yapı ve kullanıcı deneyimini artıran özellikler sunar.
Kullanılan Teknolojiler
React Native: Mobil uygulama geliştirme için kullanılan JavaScript kütüphanesi.
Expo: React Native projelerini hızlı bir şekilde başlatmak ve test etmek için kullanılan bir framework.
React Navigation: Uygulama içi gezinme (navigation) işlemleri için kullanılan kütüphane.
AsyncStorage: Verileri cihazda kalıcı olarak saklamak için kullanılan depolama çözümü.
Context API: Uygulama genelinde state yönetimi için kullanılan React’in yerleşik özelliği.
FlatList: Büyük veri listelerini performanslı bir şekilde render etmek için kullanılan bileşen.
Modal: Filtreleme işlemleri için kullanılan pop-up pencere bileşeni.
Fetch API: API’den veri çekmek için kullanılan JavaScript fonksiyonu.
2. Proje Yapısı ve Dizayn
Ürün Liste Sayfası (HomeScreen): Kullanıcıların ürünleri listeleyebileceği, arama yapabileceği ve filtreleyebileceği ana sayfa.
Ürün Detay Sayfası (ProductDetailScreen): Seçilen ürünün detaylarının gösterildiği sayfa.
Sepet Sayfası (CartScreen): Kullanıcıların sepete ekledikleri ürünleri görüntüleyebileceği ve yönetebileceği sayfa.
Favori Sayfası ( FavoriteScreen): Kullanıcıların beğendikleri ürünleri kaydedebileceği bir sayfa.
Dizayn ve Sayfa Yapısı
Projeye ilk olarak dizayn kısmından başladım. Ana sayfa (HomeScreen) için kullanıcıların ürünleri kolayca görebileceği ve filtreleyebileceği bir yapı tasarladım. Bu sayfada, ürünler 12’şer adet olarak gösteriliyor ve kullanıcı aşağı kaydırdıkça yeni ürünler yükleniyor (infinite scroll). Ayrıca, sayfanın üst kısmında bir arama çubuğu ve filtreleme butonu bulunuyor.
HomeScreen Dizaynı
Search Bar: Kullanıcıların ürünleri isme göre arayabileceği bir arama çubuğu.
Filter Button: Ürünleri fiyata göre filtreleyebileceği bir buton. Bu butona tıklandığında, bir modal açılıyor ve kullanıcı maksimum fiyat değeri girerek filtreleme yapabiliyor.
Product List: Ürünlerin iki sütun halinde gösterildiği bir liste. Her ürün kartında ürün resmi, adı, fiyatı ve sepete ekleme/favorilere ekleme butonları bulunuyor.
ProductDetailScreen Dizaynı
Product Image: Ürünün büyük bir resmi.
Product Name: Ürünün adı.
Product Description: Ürünün açıklaması.
Add to Cart Button: Ürünü sepete eklemek için bir buton.
Favorite Button: Ürünü favorilere eklemek veya favorilerden çıkarmak için bir buton.
CartScreen Dizaynı
Cart Items: Sepete eklenen ürünlerin listesi. Her ürün için adı, fiyatı ve miktarı gösteriliyor. Kullanıcı, ürün miktarını artırıp azaltabiliyor.
Total Price: Sepetteki ürünlerin toplam fiyatı.
Confirm Order Button: Siparişi onaylamak için bir buton.
FavoriteScreen Dizaynı
Product Image: Ürünün büyük bir resmi.
Product Name: Ürünün adı.
Product Description: Ürünün açıklaması.
Add to Cart Button: Ürünü sepete eklemek için bir buton.
Favorite Button: Ürünü favorilere eklemek veya favorilerden çıkarmak için bir buton.
3. Proje İçerisindeki Teknolojiler ve Kodlar
API Bağlantısı ve Ürün Listeleme
Projede, ürünleri listelemek için bir API kullanıldı. API’den gelen verileri çekmek için fetch fonksiyonu kullanıldı. API’den gelen veriler, FlatList bileşeni ile ekranda gösterildi.
useEffect(() => {
fetchAllProducts();
}, []);
const fetchAllProducts = async () => {
try {
setLoading(true);
const response = await fetch('https://5fc9346b2af77700165ae514.mockapi.io/products');
const data = await response.json();
setAllProducts(data);
applyFiltersAndPagination(data, 1);
} catch (error) {
console.error('Error fetching products:', error);
} finally {
setLoading(false);
}
};
Bu kodda, fetchAllProducts fonksiyonu ile API’den tüm ürünler çekiliyor ve setAllProducts ile state’e kaydediliyor. Daha sonra, applyFiltersAndPagination fonksiyonu ile filtreler ve sayfalama işlemleri uygulanıyor.
Infinite Scroll ve Sayfalama
Ürünler 12’şer adet olarak gösteriliyor ve kullanıcı aşağı kaydırdıkça yeni ürünler yükleniyor. Bu işlem için FlatList bileşeninin onEndReached özelliği kullanıldı.
const loadMore = () => {
if (!loading && hasMore) {
const nextPage = page + 1;
applyFiltersAndPagination(allProducts, nextPage);
}
};
<FlatList
data={filteredProducts}
keyExtractor={(item) => item.id}
renderItem={renderItem}
numColumns={2}
contentContainerStyle={styles.listContainer}
onEndReached={loadMore}
onEndReachedThreshold={0.5}
ListFooterComponent={renderFooter}
/>
Bu kodda, loadMore fonksiyonu ile bir sonraki sayfadaki ürünler yükleniyor. onEndReachedThreshold değeri, listenin ne kadar aşağı kaydırıldığında yeni verilerin yükleneceğini belirliyor.
Filtreleme İşlemleri
Kullanıcılar, ürünleri fiyata göre filtreleyebiliyor. Bu işlem için bir modal kullanıldı ve kullanıcının girdiği maksimum fiyat değerine göre filtreleme yapıldı.
const applyPriceFilter = () => {
if (!priceFilter) return;
const newFilters = {
...activeFilters,
maxPrice: priceFilter
};
setActiveFilters(newFilters);
applyFiltersAndPagination(allProducts, 1, newFilters);
setFilterModalVisible(false);
};
Bu kodda, applyPriceFilter fonksiyonu ile kullanıcının girdiği fiyat değerine göre filtreleme yapılıyor ve applyFiltersAndPagination fonksiyonu ile filtreler uygulanıyor.
Sepet İşlemleri
Sepete eklenen ürünler, AsyncStorage kullanılarak cihazda kalıcı olarak saklanıyor. Kullanıcı, sepete eklediği ürünleri uygulama kapansa bile tekrar açtığında görebiliyor.
const updateCartItem = async (productId, action) => {
let updatedCartItems = [...cartItems];
const productIndex = updatedCartItems.findIndex(item => item.id === productId);
if (productIndex !== -1) {
if (action === 'increase') {
updatedCartItems[productIndex].quantity += 1;
} else if (action === 'decrease') {
if (updatedCartItems[productIndex].quantity > 1) {
updatedCartItems[productIndex].quantity -= 1;
} else {
updatedCartItems.splice(productIndex, 1); // Ürünü tamamen kaldır
}
}
}
await AsyncStorage.setItem('cartItems', JSON.stringify(updatedCartItems));
setCartItems(updatedCartItems); // State'i güncelle
updateCartItemCount(); // Sepet sayısını güncelle
};
Bu kodda, updateCartItem fonksiyonu ile sepetteki ürün miktarı artırılıp azaltılabiliyor ve AsyncStorage ile cihazda saklanıyor.
Favori İşlemleri
Kullanıcılar, ürünleri favorilere ekleyebiliyor ve favorilerden çıkarabiliyor. Bu işlemler de AsyncStorage kullanılarak yapılıyor.
const handleFavorite = async (item) => {
if (favorites.some((fav) => fav.id === item.id)) {
await removeFromFavorites(item.id);
Alert.alert('Success', `${item.name} has been removed from favorites!`);
} else {
await addToFavorites(item);
Alert.alert('Success', `${item.name} has been added to favorites!`);
}
// Favori listesini yenile
const updatedFavorites = await getFavorites();
setFavorites(updatedFavorites);
};
Bu kodda, handleFavorite fonksiyonu ile ürün favorilere ekleniyor veya favorilerden çıkarılıyor.
Context API ile State Yönetimi
Projede, sepetteki ürün sayısını uygulama genelinde yönetmek için Context API kullanıldı. Bu sayede, sepete ürün eklendiğinde veya çıkarıldığında, tüm bileşenler bu değişiklikten haberdar olabiliyor.
const CartContext = createContext();
export const CartProvider = ({ children }) => {
const [cartItemCount, setCartItemCount] = useState(0);
const updateCartItemCount = async () => {
try {
const cartItems = await AsyncStorage.getItem('cartItems');
if (cartItems) {
const items = JSON.parse(cartItems);
const totalItems = items.reduce((sum, item) => sum + item.quantity, 0);
setCartItemCount(totalItems);
} else {
setCartItemCount(0);
}
} catch (error) {
console.error('Error updating cart count:', error);
}
};
useEffect(() => {
updateCartItemCount();
}, []);
return (
<CartContext.Provider value={{ cartItemCount, updateCartItemCount }}>
{children}
</CartContext.Provider>
);
};
Bu kodda, CartProvider bileşeni ile sepetteki ürün sayısı uygulama genelinde yönetiliyor.
4. Projenin Gereksinimleri ve Karşılanan Kriterler
Device Storage Kullanımı: Sepet ve favori işlemleri için AsyncStorage kullanıldı.
Servis İsteği: Ürünler, API’den çekilerek listelendi.
Responsive Design: Tüm sayfalar, farklı ekran boyutlarına uygun şekilde tasarlandı.
4 Ayrı Sayfa: Ürün Liste Sayfası, Ürün Detay Sayfası, Favori Sayfası ve Sepet Sayfası oluşturuldu.
Infinite Scroll: Ürünler 12’şer adet olarak listelendi ve kullanıcı aşağı kaydırdıkça yeni ürünler yüklendi.
Filtreleme ve Arama: Ürünler, fiyata göre filtrelenebiliyor ve isme göre aranabiliyor.
Context API: Sepet işlemleri için Context API kullanıldı.
Bonus Özellikler: Favori sayfası ve sepetteki ürün sayısını gösteren badge eklendi.
Bu projede, React Native Expo kullanarak bir e-ticaret uygulaması geliştirdim. Proje, kullanıcıların ürünleri listeleyebileceği, detaylarını inceleyebileceği, sepete ekleyebileceği ve favorilere ekleyebileceği bir yapıya sahip. Projenin her aşamasını, kullanılan teknolojileri ve kodların neden bu şekilde yazıldığını detaylı bir şekilde açıkladım. Bu makaleyi okuyan bir insan, projenin her detayına hakim olabilir ve benzer bir proje geliştirebilir. Github profilimden uygulamanın görsellerine ve kod yapısına ulaşabilirsiniz.