I'm trying to build a marketplace at the moment but I'm having difficulties dispatching data with the reducer.js component.
I'm trying to use a currency Input form to change the quantity/amount that my subtotal component displays (subtotal = item.price * $amount)
here's my Product.js responsible for the basket variables and Input HTML:
import React, { useState } from "react"; import "./Product.css"; import { useStateValue } from "./StateProvider"; import InfoIcon from '@material-ui/icons/Info'; import InputNumber from 'react-input-number'; function Product({ id, title, image, price, info, total, quantity }) { const [{ basket }, dispatch] = useStateValue(); const [num, setNum] = useState(); const addToBasket = () => { dispatch({ type: "ADD_TO_BASKET", item: { id: id, title: title, image: image, price: price, info: info, total: total, quantity: quantity, }, }); }; return ( <div className="product"> <div className="product__info"> <p>{title}</p> <p className="product__price"> <small>$</small> <strong>{price}</strong> </p> <form> <label> Amount: <InputNumber type="number" min={10} max={100} step={0.03} value={num} onChange={quantity}></InputNumber> </label> </form> <div className="product__info"> {Array(info) .fill() .map((_, i) => ( <p></p> ))} </div> </div> <img src={image} alt="" /> <button onClick={addToBasket}>Purchase</button> </div> ); } export default Product;
reducer.js component:
export const initialState = { basket: [], user: null, }; // Selector export const getBasketTotal = (basket) => basket?.reduce((amount, item) => (item.price * item.quantity) + amount, 0); const reducer = (state, action) => { console.log(action); switch (action.type) { case 'ADD_TO_BASKET': return { ...state, basket: [...state.basket, action.item], }; case "REMOVE_FROM_BASKET": const index = state.basket.findIndex( (basketItem) => basketItem.id === action.id ); let newBasket = [...state.basket]; if (index >= 0) { newBasket.splice(index, 1); } else { console.warn( `Can't remove product ${action.id} as it's not in the basket! ` ) } return { ...state, basket: newBasket } case "SET_USER": return { ...state, user: action.user, } default: return state; } }; export default reducer;
and the Subtotal.js component:
import React from 'react'; import "./Subtotal.css"; import CurrencyFormat from "react-currency-format"; import { useStateValue } from './StateProvider'; import { getBasketTotal } from './reducer'; import { useHistory } from 'react-router'; function Subtotal() { const history = useHistory(); const [{basket}, dispatch] = useStateValue(); return ( <div className="subtotal"> <CurrencyFormat renderText={(value) => ( <> <p> Subtotal ({basket.length} items): <strong>{value}</strong> </p> {/* <small className="subtotal__gift"> <input type="checkbox" /> this order contains a gift </small> */} </> )} decimalScale={2} value={getBasketTotal(basket)} displayType={"text"} thousandSeperator={true} prefix={"$"} /> <button onClick={e => history.push('/payment')}>Proceed to Checkout</button> </div> ); } export default Subtotal;
Does anyone know why the Subtotal is returning NaNaNaN and how to go about fixing it?
Thanks in advance
https://stackoverflow.com/questions/67030185/getbaskettotal-is-returning-nananan-reactjs April 10, 2021 at 10:07AM
没有评论:
发表评论