Today, you’ll implement a shopping cart for your e-commerce app. The shopping cart will allow users to add products and view their selected items. You’ll use AsyncStorage for persistent storage, enabling users to retain their cart items even if they close the app.
What You Will Do Today:
- Set up AsyncStorage to save cart items.
- Create a shopping cart context to manage cart state globally.
- Implement functions to add, view, and remove items from the cart.
Step 1: Installing AsyncStorage
- Install the @react-native-async-storage/async-storage package:
npm install @react-native-async-storage/async-storage
- Import AsyncStorage in your app where necessary.
Step 2: Setting Up Cart Context for Global State Management
- In the
src
folder, create a new folder calledcontext
and add a file namedCartContext.js
.
// src/context/CartContext.js
import React, { createContext, useState, useEffect } from 'react';
import AsyncStorage from '@react-native-async-storage/async-storage';
export const CartContext = createContext();
export const CartProvider = ({ children }) => {
const [cart, setCart] = useState([]);
useEffect(() => {
const loadCart = async () => {
const cartData = await AsyncStorage.getItem('cart');
if (cartData) setCart(JSON.parse(cartData));
};
loadCart();
}, []);
const saveCart = async (updatedCart) => {
setCart(updatedCart);
await AsyncStorage.setItem('cart', JSON.stringify(updatedCart));
};
const addToCart = (product) => {
const updatedCart = [...cart, product];
saveCart(updatedCart);
};
const removeFromCart = (productId) => {
const updatedCart = cart.filter((item) => item.id !== productId);
saveCart(updatedCart);
};
return (
<CartContext.Provider value={{ cart, addToCart, removeFromCart }}>
{children}
</CartContext.Provider>
);
};
Explanation of Code:
- CartContext: Provides global access to the cart.
- addToCart and removeFromCart: Functions to add and remove items in the cart.
- AsyncStorage: Persists cart data, so it’s saved even if the app is closed.
- Wrap the
App.js
component withCartProvider
to provide cart data to all screens.
// App.js
import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import LoginScreen from './screens/LoginScreen';
import ProductList from './screens/ProductList';
import ProductDetail from './screens/ProductDetail';
import { CartProvider } from './context/CartContext';
const Stack = createStackNavigator();
export default function App() {
return (
<CartProvider>
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="LoginScreen" component={LoginScreen} options={{ title: 'Login' }} />
<Stack.Screen name="ProductList" component={ProductList} options={{ title: 'Products' }} />
<Stack.Screen name="ProductDetail" component={ProductDetail} options={{ title: 'Product Details' }} />
</Stack.Navigator>
</NavigationContainer>
</CartProvider>
);
}
Step 3: Adding “Add to Cart” Functionality on Product Detail Page
- In
ProductDetail.js
, add a button to allow users to add items to the cart.
// screens/ProductDetail.js
import React, { useContext } from 'react';
import { View, Text, Button, StyleSheet } from 'react-native';
import { CartContext } from '../context/CartContext';
import firestore from '@react-native-firebase/firestore';
function ProductDetail({ route }) {
const { productId } = route.params;
const [product, setProduct] = useState(null);
const { addToCart } = useContext(CartContext);
useEffect(() => {
const fetchProduct = async () => {
const doc = await firestore().collection('products').doc(productId).get();
if (doc.exists) setProduct({ id: doc.id, ...doc.data() });
};
fetchProduct();
}, [productId]);
if (!product) {
return (
<View style={styles.container}>
<Text>Loading...</Text>
</View>
);
}
return (
<View style={styles.container}>
<Text style={styles.productName}>{product.name}</Text>
<Text style={styles.productPrice}>${product.price.toFixed(2)}</Text>
<Text style={styles.productDescription}>{product.description}</Text>
<Button title="Add to Cart" onPress={() => addToCart(product)} />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 16,
},
productName: {
fontSize: 24,
fontWeight: 'bold',
marginBottom: 8,
},
productPrice: {
fontSize: 20,
color: '#888',
marginBottom: 8,
},
productDescription: {
fontSize: 16,
color: '#555',
},
});
export default ProductDetail;
Step 4: Creating a Cart Screen
- In the
screens
folder, createCartScreen.js
to display cart items.
// screens/CartScreen.js
import React, { useContext } from 'react';
import { View, Text, FlatList, Button, StyleSheet } from 'react-native';
import { CartContext } from '../context/CartContext';
function CartScreen() {
const { cart, removeFromCart } = useContext(CartContext);
const renderItem = ({ item }) => (
<View style={styles.cartItem}>
<Text style={styles.cartItemText}>{item.name}</Text>
<Text style={styles.cartItemPrice}>${item.price.toFixed(2)}</Text>
<Button title="Remove" onPress={() => removeFromCart(item.id)} />
</View>
);
return (
<View style={styles.container}>
<Text style={styles.title}>Your Cart</Text>
<FlatList
data={cart}
renderItem={renderItem}
keyExtractor={(item) => item.id}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 16,
},
title: {
fontSize: 24,
fontWeight: 'bold',
marginBottom: 16,
},
cartItem: {
padding: 16,
marginVertical: 8,
backgroundColor: '#f9f9f9',
borderRadius: 8,
borderWidth: 1,
borderColor: '#ddd',
},
cartItemText: {
fontSize: 18,
},
cartItemPrice: {
fontSize: 16,
color: '#888',
},
});
export default CartScreen;
- Add the CartScreen to the navigation stack in
App.js
:
// App.js
import CartScreen from './screens/CartScreen';
// Add CartScreen to the Stack.Navigator
<Stack.Screen name="CartScreen" component={CartScreen} options={{ title: 'Cart' }} />
- Add a button in ProductList to navigate to the Cart Screen:
// screens/ProductList.js
<Button title="View Cart" onPress={() => navigation.navigate('CartScreen')} />
Summary
Today, you implemented a shopping cart for your app using AsyncStorage for persistent data. Users can now add items to the cart, view their selected products, and remove them if needed.
Tomorrow, you’ll set up a payment gateway to enable in-app purchases for the selected items.