No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Curso Práctico de React.js

Curso Práctico de React.js

Oscar Barajas Tavares

Oscar Barajas Tavares

Calculando el precio total

25/30
Recursos

Aportes 15

Preguntas 10

Ordenar por:

Los aportes, preguntas y respuestas son vitales para aprender en comunidad. Regístrate o inicia sesión para participar.

Para calcular el precio real de los elementos añadidos al carrito y poder mostrar la información correctamente, trabajaremos sobre MyOrder y OrderItem.

// OrderItem.jsx
import React from 'react';

const OrderItem = ({ product }) => {
	return (
		<div className="OrderItem">
			<figure>
				<img src={product.images[0]} alt={product.title} />
			</figure>
			<p>{product.title}</p>
			<p>{product.price}</p>
			<img src={icon_close} alt="close" />
		</div>
	);
}

export default OrderItem;

Primero, en OrderItem recordemos que desde MyOrder le estabamos pasando el producto. Sin embargo, en todos los casos estábamos mostrando una bicicleta. Ahora, para poder mostrar la información de cada producto, simplemente le indicamos al componente que recibimos como parámetro un product. Después, editamos el HTML, para que la imágen, título y precio correspondan al del producto, así que solamente accedemos a las propiedades de cada uno.

// MyOrder.jsx
const MyOrder = () => {
	const { state } = useContext(AppContext);

	const sumTotal = () => {
		const reducer = (accumulator, currentValue) => accumulator + currentValue.price;
		const sum = state.cart.reduce(reducer, 0);
		return sum;
	}

	return (
		<div className="order">
				<p>
					<span>Total</span>
				</p>
			<p>${sumTotal()}</p>
		</div>
	);
}

export default MyOrder;

Ahora, editemos el componente MyOrder. En my order, creamos una función llamada sumTotal donde creamos la lógica de la suma de los precios de los productos del carrito. Para poder crear esta función, primero creamos la función llamada reducer, en la cual le pasamos dos valores, un acumulador y un valor corriente, para después regresar la suma de ambos. Después, en la constante sum, usamos el método reduce para los arrays. El método se aplica sobre el array state.cart con todos estos elementos. Simplemente, le pasamos la función antes definida, y un valor inicial igual a cero. Por último, regresamos sum. Más abajo, en la etiqueta p, entre llaves indicamos que se ejecute esta función para calcular el precio cada vez que se renderice el componente.

Directamente hice la suma en el
useInitialState, agregando dos funciones que hacen este trabajo.
Para luego, si quiero acceder al valor TOTAL , lo puedo hacer desde cualquier lugar

import { useState } from "react";

const initialState = {
	cart: [],
	total:0,
}

const useInitialState = () => {
	const [state, setState] = useState(initialState);
 
 
	const addToCart = (payload) => {
		if(!state.cart.includes(payload)){
			setState({
				...state,
				cart: [...state.cart, payload],
				total: state.total + payload.price
			});
 
		}
	};
	const removeFromCart = (payload) =>{
		const newArray = state.cart.filter(product => product != payload);
		setState({
			...state,
			cart: [...newArray],
			total: state.total - payload.price
		});
 
 
	}
	return {
		state,
		addToCart,
		removeFromCart
	}
}

export default useInitialState;

Aquí comparto un link con info sobre el método reduce() para su mayor compresión.
https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce

No pude completar esta clase: simplemenete mi componente OrderItem por alguna razon no recibe correctamente { product }. Me sale exactamente el mismo error en consola que al profe, pero no lo arreglo la S como en la clase. Que frustrante.

otra forma de realizar la función seria:

const sumTotal = () => {
  let total = 0;
  state.cart.forEach(product => {
  total += product.price;
  });
 return total;
}

<div className="order">
  <p>
  <span>Total</span>
  </p>
  <p>{sumTotal()}</p>
</div>

Estuve 2 horas sin que me saliera, verifiquen el archivo MyOrder que esta en containers.

Yo tenia importe 2 veces OrderItem dentro del archivo y era el porque no me salia jaja.

Jamas se rindan, ya le estoy agarrando el gusto a reirme de errores bien tontos que tengo.

Yo sume el total dentro de la etiqueta p usando metodos de manipulación de arrays

<p>${state.cart.map(product => parseFloat(product.price)).reduce((a,b) => a + b)}</p>

Enlaces

Ahora con el código que hace el profe en la suma total aparece un NaN y eso es porque estamos retornando un Array. Lo único que haremos es lo siguiente:

const sumTotal = () => {
		const reducer = (accumalator, currentValue) => accumalator + currentValue[0].price
		const sum = state.cart.reduce(reducer, 0)
console.log(state.cart)
		return sum
	}

Me di cuenta cuando revise que estaba retornando con el console.log

Hay un bug al seleccionar el mismo item, al hacer eso, se asigna el mismo key en la iteración y esto lo marca como error en la consola

Otra manera de sacar la suma total es con la función .reduce() de JS:

const totalPrice = cartInfo.reduce((total, currentObj) => {
    return total += currentObj.price
  }, 0);

Agregue la siguiente fn() para que en el total nos de el formato en USD y ver los respectivos decimales.

const formatoPrecio = (valor) => {
        const formatoUSD = new window.Intl.NumberFormat('en-EN', {
            style: 'currency',
            currency: 'USD'
        }).format(valor)
        return formatoUSD
    }

<p>{formatoPrecio(sumTotal())}</p>
//MyOrder.jsx
import React, {useContext} from 'react';
import OrderItem from '@components/OrderItem';
import '../styles/MyOrder.scss';
import AppContext from '../context/AppContext';
import arrow from '@icons/flechita.svg';

const MyOrder = () => {
	const { state } = useContext(AppContext);
	state.cart.map(product => {console.log(product[0])})
	return (
		<aside className="MyOrder">
			<div className="title-container">
				<img src={arrow} alt="arrow" />
				<p className="title">My order</p>
			</div>
			<div className="my-order-content">
				{state.cart.map(product => (
					<OrderItem product={product[0]} key={`orderItem-${product[0].id}`} />
				))}
				<div className="order">
					<p>
						<span>Total</span>
					</p>
					<p>$560.00</p>
				</div>
				<button className="primary-button">
					Checkout
				</button>
			</div>
		</aside>
	);
}

export default MyOrder;

si alguien tiene un error de undefined con react 17 se debe enviar product[0] al children por una actualizacion de react si no me equivoco.

Yo encontré el precio total de esta manera…


const priceStateInit = state.cart.map( (product) => parseInt(product.price))
const handlePriceTotal =  priceStateInit.reduce((accum=0,productPrice) => accum+productPrice);


${handlePriceTotal}