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

  1. Configuració inicial
  2. Pantalla de Llista de Productes
  3. Pantalla de Detalls del Producte
  4. Pantalla del Carret de Compra
  5. Pantalla de Pagament
  6. Integració amb API
  7. Gestió de l'Estat amb Context API
  8. Estilització i Optimització

  1. 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;

  1. 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;

  1. 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;

  1. 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;

  1. 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;

  1. 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]);

  1. 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>
  );
}

  1. 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.

© Copyright 2024. Tots els drets reservats