In this project, we will build a simple e-commerce application using React Native. This project will help you understand how to integrate various concepts learned in the previous modules, such as state management, navigation, networking, and more.
Objectives
- Create a user-friendly interface for browsing products.
- Implement navigation between different screens.
- Fetch product data from an API.
- Handle user actions such as adding items to the cart.
- Manage state for the shopping cart.
- Persist cart data using AsyncStorage.
Project Structure
- Setting Up the Project
- Creating the Product List Screen
- Implementing Product Details Screen
- Building the Shopping Cart
- Persisting Cart Data
- Final Touches and Testing
- Setting Up the Project
Step 1: Initialize the Project
First, create a new React Native project using the following command:
Step 2: Install Required Packages
Install the necessary packages for navigation and state management:
npm install @react-navigation/native @react-navigation/stack @react-navigation/bottom-tabs npm install react-native-gesture-handler react-native-reanimated react-native-screens react-native-safe-area-context @react-native-community/masked-view npm install axios npm install @react-native-async-storage/async-storage
Step 3: Set Up Navigation
Create a navigation
folder and add a MainNavigator.js
file:
// navigation/MainNavigator.js import React from 'react'; import { NavigationContainer } from '@react-navigation/native'; import { createStackNavigator } from '@react-navigation/stack'; import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; import ProductListScreen from '../screens/ProductListScreen'; import ProductDetailsScreen from '../screens/ProductDetailsScreen'; import CartScreen from '../screens/CartScreen'; const Stack = createStackNavigator(); const Tab = createBottomTabNavigator(); const MainNavigator = () => { return ( <NavigationContainer> <Tab.Navigator> <Tab.Screen name="Products" component={ProductStackNavigator} /> <Tab.Screen name="Cart" component={CartScreen} /> </Tab.Navigator> </NavigationContainer> ); }; const ProductStackNavigator = () => { return ( <Stack.Navigator> <Stack.Screen name="ProductList" component={ProductListScreen} /> <Stack.Screen name="ProductDetails" component={ProductDetailsScreen} /> </Stack.Navigator> ); }; export default MainNavigator;
Step 4: Update App.js
Update App.js
to use the MainNavigator
:
// App.js import React from 'react'; import MainNavigator from './navigation/MainNavigator'; const App = () => { return <MainNavigator />; }; export default App;
- Creating the Product List Screen
Step 1: Create ProductListScreen Component
Create a screens
folder and add a ProductListScreen.js
file:
// screens/ProductListScreen.js import React, { useEffect, useState } from 'react'; import { View, Text, FlatList, TouchableOpacity, StyleSheet } from 'react-native'; import axios from 'axios'; const ProductListScreen = ({ navigation }) => { const [products, setProducts] = useState([]); useEffect(() => { axios.get('https://fakestoreapi.com/products') .then(response => setProducts(response.data)) .catch(error => console.error(error)); }, []); const renderItem = ({ item }) => ( <TouchableOpacity onPress={() => navigation.navigate('ProductDetails', { product: item })}> <View style={styles.item}> <Text style={styles.title}>{item.title}</Text> </View> </TouchableOpacity> ); return ( <FlatList data={products} renderItem={renderItem} keyExtractor={item => item.id.toString()} /> ); }; const styles = StyleSheet.create({ item: { padding: 20, borderBottomWidth: 1, borderBottomColor: '#ccc', }, title: { fontSize: 18, }, }); export default ProductListScreen;
- Implementing Product Details Screen
Step 1: Create ProductDetailsScreen Component
Create a ProductDetailsScreen.js
file in the screens
folder:
// screens/ProductDetailsScreen.js import React from 'react'; import { View, Text, Button, StyleSheet } from 'react-native'; const ProductDetailsScreen = ({ route, navigation }) => { const { product } = route.params; return ( <View style={styles.container}> <Text style={styles.title}>{product.title}</Text> <Text style={styles.description}>{product.description}</Text> <Text style={styles.price}>${product.price}</Text> <Button title="Add to Cart" onPress={() => {/* Add to cart logic */}} /> </View> ); }; const styles = StyleSheet.create({ container: { padding: 20, }, title: { fontSize: 24, fontWeight: 'bold', }, description: { fontSize: 16, marginVertical: 10, }, price: { fontSize: 20, color: 'green', marginVertical: 10, }, }); export default ProductDetailsScreen;
- Building the Shopping Cart
Step 1: Create CartScreen Component
Create a CartScreen.js
file in the screens
folder:
// screens/CartScreen.js import React, { useState } from 'react'; import { View, Text, FlatList, Button, StyleSheet } from 'react-native'; const CartScreen = () => { const [cartItems, setCartItems] = useState([]); const renderItem = ({ item }) => ( <View style={styles.item}> <Text style={styles.title}>{item.title}</Text> <Text style={styles.price}>${item.price}</Text> </View> ); return ( <View style={styles.container}> <FlatList data={cartItems} renderItem={renderItem} keyExtractor={item => item.id.toString()} /> <Button title="Checkout" onPress={() => {/* Checkout logic */}} /> </View> ); }; const styles = StyleSheet.create({ container: { padding: 20, }, item: { padding: 20, borderBottomWidth: 1, borderBottomColor: '#ccc', }, title: { fontSize: 18, }, price: { fontSize: 16, color: 'green', }, }); export default CartScreen;
- Persisting Cart Data
Step 1: Install AsyncStorage
Ensure AsyncStorage is installed:
Step 2: Update Cart Logic
Update the CartScreen
and ProductDetailsScreen
to use AsyncStorage for persisting cart data:
// screens/CartScreen.js import React, { useState, useEffect } from 'react'; import { View, Text, FlatList, Button, StyleSheet } from 'react-native'; import AsyncStorage from '@react-native-async-storage/async-storage'; const CartScreen = () => { const [cartItems, setCartItems] = useState([]); useEffect(() => { const loadCart = async () => { const cart = await AsyncStorage.getItem('cart'); if (cart) { setCartItems(JSON.parse(cart)); } }; loadCart(); }, []); const renderItem = ({ item }) => ( <View style={styles.item}> <Text style={styles.title}>{item.title}</Text> <Text style={styles.price}>${item.price}</Text> </View> ); return ( <View style={styles.container}> <FlatList data={cartItems} renderItem={renderItem} keyExtractor={item => item.id.toString()} /> <Button title="Checkout" onPress={() => {/* Checkout logic */}} /> </View> ); }; const styles = StyleSheet.create({ container: { padding: 20, }, item: { padding: 20, borderBottomWidth: 1, borderBottomColor: '#ccc', }, title: { fontSize: 18, }, price: { fontSize: 16, color: 'green', }, }); export default CartScreen;
// screens/ProductDetailsScreen.js import React from 'react'; import { View, Text, Button, StyleSheet } from 'react-native'; import AsyncStorage from '@react-native-async-storage/async-storage'; const ProductDetailsScreen = ({ route, navigation }) => { const { product } = route.params; const addToCart = async () => { const cart = await AsyncStorage.getItem('cart'); let cartItems = cart ? JSON.parse(cart) : []; cartItems.push(product); await AsyncStorage.setItem('cart', JSON.stringify(cartItems)); alert('Item added to cart'); }; return ( <View style={styles.container}> <Text style={styles.title}>{product.title}</Text> <Text style={styles.description}>{product.description}</Text> <Text style={styles.price}>${product.price}</Text> <Button title="Add to Cart" onPress={addToCart} /> </View> ); }; const styles = StyleSheet.create({ container: { padding: 20, }, title: { fontSize: 24, fontWeight: 'bold', }, description: { fontSize: 16, marginVertical: 10, }, price: { fontSize: 20, color: 'green', marginVertical: 10, }, }); export default ProductDetailsScreen;
- Final Touches and Testing
Step 1: Test the Application
Run the application on your emulator or physical device:
Step 2: Verify Functionality
- Ensure you can navigate between the product list and product details screens.
- Verify that products can be added to the cart and that the cart persists between app restarts.
Conclusion
In this project, you have built a simple e-commerce application using React Native. You have learned how to:
- Set up navigation between different screens.
- Fetch and display data from an API.
- Handle user actions and manage state.
- Persist data using AsyncStorage.
This project has provided a comprehensive overview of how to build a real-world application with React Native, integrating various concepts and techniques. Continue to explore and enhance this application by adding more features, such as user authentication, payment integration, and more.
React Native Course
Module 1: Introduction to React Native
- What is React Native?
- Setting Up the Development Environment
- Hello World App
- Understanding JSX
- Components and Props
Module 2: Core Components and Styling
- Core Components Overview
- Text, View, and Image
- Styling with Flexbox
- Handling User Input
- ScrollView and ListView
Module 3: State and Lifecycle
- State and Lifecycle Methods
- Handling Events
- Conditional Rendering
- Lists and Keys
- Forms and Controlled Components
Module 4: Navigation
- Introduction to React Navigation
- Stack Navigator
- Tab Navigator
- Drawer Navigator
- Passing Parameters to Routes
Module 5: Networking and Data
- Fetching Data with Fetch API
- Using Axios for HTTP Requests
- Handling Network Errors
- AsyncStorage for Local Data
- Integrating with REST APIs
Module 6: Advanced Concepts
Module 7: Deployment and Publishing
- Building for iOS
- Building for Android
- Publishing to App Store
- Publishing to Google Play
- Continuous Integration and Delivery