En aquest projecte, desenvoluparem una aplicació de comerç electrònic utilitzant React Native. Aquest projecte ens permetrà aplicar molts dels conceptes apresos en els mòduls anteriors, com ara la gestió de l'estat, la navegació, la integració amb APIs i l'estilització.
Objectius del Projecte
- Crear una interfície d'usuari atractiva i funcional per a una aplicació de comerç electrònic.
- Implementar la navegació entre diferents pantalles.
- Integrar una API per obtenir dades de productes.
- Gestionar l'estat de l'aplicació utilitzant Context API i Hooks.
- Implementar funcionalitats com la cerca de productes, el carret de compra i el procés de pagament.
Estructura del Projecte
- Configuració inicial
- Pantalla de Llista de Productes
- Pantalla de Detalls del Producte
- Pantalla del Carret de Compra
- Pantalla de Pagament
- Integració amb API
- Gestió de l'Estat amb Context API
- Estilització i Optimització
- Configuració inicial
Instal·lació de dependències
Primer, crearem un nou projecte de React Native i instal·larem les dependències necessàries.
npx react-native init EcommerceApp cd EcommerceApp npm install @react-navigation/native @react-navigation/stack 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
Configuració de la navegació
Afegirem la configuració bàsica per a la navegació.
// App.js import 'react-native-gesture-handler'; import * as React from 'react'; import { NavigationContainer } from '@react-navigation/native'; import { createStackNavigator } from '@react-navigation/stack'; import ProductListScreen from './screens/ProductListScreen'; import ProductDetailScreen from './screens/ProductDetailScreen'; import CartScreen from './screens/CartScreen'; import CheckoutScreen from './screens/CheckoutScreen'; const Stack = createStackNavigator(); function App() { return ( <NavigationContainer> <Stack.Navigator initialRouteName="ProductList"> <Stack.Screen name="ProductList" component={ProductListScreen} /> <Stack.Screen name="ProductDetail" component={ProductDetailScreen} /> <Stack.Screen name="Cart" component={CartScreen} /> <Stack.Screen name="Checkout" component={CheckoutScreen} /> </Stack.Navigator> </NavigationContainer> ); } export default App;
- Pantalla de Llista de Productes
Creació del component
Crearem un component per mostrar la llista de productes.
// 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://api.example.com/products') .then(response => setProducts(response.data)) .catch(error => console.error(error)); }, []); return ( <View style={styles.container}> <FlatList data={products} keyExtractor={item => item.id.toString()} renderItem={({ item }) => ( <TouchableOpacity onPress={() => navigation.navigate('ProductDetail', { productId: item.id })}> <View style={styles.productItem}> <Text style={styles.productName}>{item.name}</Text> <Text style={styles.productPrice}>${item.price}</Text> </View> </TouchableOpacity> )} /> </View> ); }; const styles = StyleSheet.create({ container: { flex: 1, padding: 16, }, productItem: { padding: 16, borderBottomWidth: 1, borderBottomColor: '#ccc', }, productName: { fontSize: 18, }, productPrice: { fontSize: 16, color: '#888', }, }); export default ProductListScreen;
- Pantalla de Detalls del Producte
Creació del component
Crearem un component per mostrar els detalls d'un producte seleccionat.
// screens/ProductDetailScreen.js import React, { useEffect, useState } from 'react'; import { View, Text, Button, StyleSheet } from 'react-native'; import axios from 'axios'; const ProductDetailScreen = ({ route, navigation }) => { const { productId } = route.params; const [product, setProduct] = useState(null); useEffect(() => { axios.get(`https://api.example.com/products/${productId}`) .then(response => setProduct(response.data)) .catch(error => console.error(error)); }, [productId]); if (!product) { return <Text>Loading...</Text>; } return ( <View style={styles.container}> <Text style={styles.productName}>{product.name}</Text> <Text style={styles.productPrice}>${product.price}</Text> <Text style={styles.productDescription}>{product.description}</Text> <Button title="Add to Cart" onPress={() => navigation.navigate('Cart', { product })} /> </View> ); }; const styles = StyleSheet.create({ container: { flex: 1, padding: 16, }, productName: { fontSize: 24, fontWeight: 'bold', }, productPrice: { fontSize: 20, color: '#888', }, productDescription: { fontSize: 16, marginVertical: 16, }, }); export default ProductDetailScreen;
- Pantalla del Carret de Compra
Creació del component
Crearem un component per mostrar els productes afegits al carret de compra.
// screens/CartScreen.js import React, { useContext } from 'react'; import { View, Text, FlatList, Button, StyleSheet } from 'react-native'; import { CartContext } from '../context/CartContext'; const CartScreen = ({ navigation }) => { const { cartItems, removeFromCart } = useContext(CartContext); return ( <View style={styles.container}> <FlatList data={cartItems} keyExtractor={item => item.id.toString()} renderItem={({ item }) => ( <View style={styles.cartItem}> <Text style={styles.productName}>{item.name}</Text> <Text style={styles.productPrice}>${item.price}</Text> <Button title="Remove" onPress={() => removeFromCart(item.id)} /> </View> )} /> <Button title="Proceed to Checkout" onPress={() => navigation.navigate('Checkout')} /> </View> ); }; const styles = StyleSheet.create({ container: { flex: 1, padding: 16, }, cartItem: { padding: 16, borderBottomWidth: 1, borderBottomColor: '#ccc', }, productName: { fontSize: 18, }, productPrice: { fontSize: 16, color: '#888', }, }); export default CartScreen;
- Pantalla de Pagament
Creació del component
Crearem un component per gestionar el procés de pagament.
// screens/CheckoutScreen.js import React, { useContext } from 'react'; import { View, Text, Button, StyleSheet } from 'react-native'; import { CartContext } from '../context/CartContext'; const CheckoutScreen = ({ navigation }) => { const { cartItems, clearCart } = useContext(CartContext); const handleCheckout = () => { // Aquí es gestionaria el procés de pagament clearCart(); navigation.navigate('ProductList'); }; return ( <View style={styles.container}> <Text style={styles.title}>Checkout</Text> <FlatList data={cartItems} keyExtractor={item => item.id.toString()} renderItem={({ item }) => ( <View style={styles.cartItem}> <Text style={styles.productName}>{item.name}</Text> <Text style={styles.productPrice}>${item.price}</Text> </View> )} /> <Button title="Complete Purchase" onPress={handleCheckout} /> </View> ); }; const styles = StyleSheet.create({ container: { flex: 1, padding: 16, }, title: { fontSize: 24, fontWeight: 'bold', marginBottom: 16, }, cartItem: { padding: 16, borderBottomWidth: 1, borderBottomColor: '#ccc', }, productName: { fontSize: 18, }, productPrice: { fontSize: 16, color: '#888', }, }); export default CheckoutScreen;
- Integració amb API
Obtenir dades de productes
Utilitzarem Axios per obtenir dades de productes des d'una API.
// screens/ProductListScreen.js useEffect(() => { axios.get('https://api.example.com/products') .then(response => setProducts(response.data)) .catch(error => console.error(error)); }, []);
Obtenir detalls del producte
Utilitzarem Axios per obtenir els detalls d'un producte seleccionat.
// screens/ProductDetailScreen.js useEffect(() => { axios.get(`https://api.example.com/products/${productId}`) .then(response => setProduct(response.data)) .catch(error => console.error(error)); }, [productId]);
- Gestió de l'Estat amb Context API
Creació del context
Crearem un context per gestionar l'estat del carret de compra.
// context/CartContext.js import React, { createContext, useState } from 'react'; export const CartContext = createContext(); export const CartProvider = ({ children }) => { const [cartItems, setCartItems] = useState([]); const addToCart = (product) => { setCartItems([...cartItems, product]); }; const removeFromCart = (productId) => { setCartItems(cartItems.filter(item => item.id !== productId)); }; const clearCart = () => { setCartItems([]); }; return ( <CartContext.Provider value={{ cartItems, addToCart, removeFromCart, clearCart }}> {children} </CartContext.Provider> ); };
Utilització del context
Utilitzarem el context en els components rellevants.
// App.js import { CartProvider } from './context/CartContext'; function App() { return ( <CartProvider> <NavigationContainer> <Stack.Navigator initialRouteName="ProductList"> <Stack.Screen name="ProductList" component={ProductListScreen} /> <Stack.Screen name="ProductDetail" component={ProductDetailScreen} /> <Stack.Screen name="Cart" component={CartScreen} /> <Stack.Screen name="Checkout" component={CheckoutScreen} /> </Stack.Navigator> </NavigationContainer> </CartProvider> ); }
- Estilització i Optimització
Estilització
Afegirem estils per millorar l'aparença de l'aplicació.
// screens/ProductListScreen.js const styles = StyleSheet.create({ container: { flex: 1, padding: 16, }, productItem: { padding: 16, borderBottomWidth: 1, borderBottomColor: '#ccc', }, productName: { fontSize: 18, }, productPrice: { fontSize: 16, color: '#888', }, });
Optimització
Implementarem optimitzacions com l'ús de React.memo
per evitar renderitzacions innecessàries.
// components/ProductItem.js import React from 'react'; import { View, Text, TouchableOpacity, StyleSheet } from 'react-native'; const ProductItem = React.memo(({ product, onPress }) => ( <TouchableOpacity onPress={onPress}> <View style={styles.productItem}> <Text style={styles.productName}>{product.name}</Text> <Text style={styles.productPrice}>${product.price}</Text> </View> </TouchableOpacity> )); const styles = StyleSheet.create({ productItem: { padding: 16, borderBottomWidth: 1, borderBottomColor: '#ccc', }, productName: { fontSize: 18, }, productPrice: { fontSize: 16, color: '#888', }, }); export default ProductItem;
Conclusió
En aquest projecte, hem creat una aplicació de comerç electrònic completa utilitzant React Native. Hem après a configurar la navegació, obtenir dades d'una API, gestionar l'estat amb Context API i estilitzar els components. Aquest projecte ens ha permès aplicar molts dels conceptes apresos en els mòduls anteriors i ens ha preparat per desenvolupar aplicacions més complexes en el futur.
Curs de React Native
Mòdul 1: Introducció a React Native
- Què és React Native?
- Configuració de l'entorn de desenvolupament
- Aplicació Hello World
- Comprendre JSX
- Components i Props
Mòdul 2: Components bàsics i estilització
- Visió general dels components bàsics
- Text, View i Image
- Estilització amb Flexbox
- Gestió de l'entrada de l'usuari
- ScrollView i ListView
Mòdul 3: Estat i cicle de vida
- Mètodes d'estat i cicle de vida
- Gestió d'esdeveniments
- Renderització condicional
- Llistes i claus
- Formularis i components controlats
Mòdul 4: Navegació
- Introducció a React Navigation
- Stack Navigator
- Tab Navigator
- Drawer Navigator
- Passar paràmetres a les rutes
Mòdul 5: Xarxes i dades
- Obtenir dades amb Fetch API
- Utilitzar Axios per a sol·licituds HTTP
- Gestió d'errors de xarxa
- AsyncStorage per a dades locals
- Integració amb APIs REST
Mòdul 6: Conceptes avançats
Mòdul 7: Desplegament i publicació
- Construcció per a iOS
- Construcció per a Android
- Publicació a l'App Store
- Publicació a Google Play
- Integració i lliurament continus