karim Salim
karim Salim

Reputation: 93

How to calculate the total price of items with button in React.js?

I'm working on a billing app. I have managed to fetch Products from an API.. now i want to calculate the total price and display it every time the user click's on either the add or minus button.

I tried to use addEventListener() and onClick() but neither of these two worked with me, am probably doing something wrong but i am not sure what is it!

I would really appreciate some help or feedback, thanks.

enter image description here

Here's my code: Sorry if my code is messy, i'm still learning Javascript and React.js.

    import React, { useState } from "react";
import "./Bill.css";
import { Link, useParams, Switch, Route } from "react-router-dom";
import { connect } from "react-redux";
import { getItems } from "../store/actions/itemsActions";


function BillList({  items }) {
  

  const [counter, setCounter] = useState(1);

 
  // will display the current number

  function Display(props) {
    return <label style={{ marginLeft: ".5rem" }}>{props.message}</label>;
  }


    const params = useParams();
    return (
      <div className="bills">
        <div
          className="main-title"
          style={{
            textAlign: "center",
            justifyContent: "center",
            alignItems: "center",
            fontSize: 14,
          }}
        >
          
          <h1>Bakery</h1>
          <h1>Company Gbr</h1>
          <h1>Oranienburger Straße 120</h1>
          <h1>10119 Berlin</h1>
        </div>
        
  
        <div className="bills-container">
          <div></div>
  
          {/* pass in the details  */}
          <div className="item-list">
            {items &&
              items.items &&
              items.items.map((item) => (
                <React.Fragment key={item.id}>
                 
                  <div className="bill-time">
                    <div className="bill">
                      <h4>
                        {" "}
                        <strong>Bill: </strong>
                        {item.billNumber}
                      </h4>
                    </div>
                    
  
                   
                    {/* <div style={{flex: 1,textAlign: 'right'}} className="time-date"> */}
                    <div className="time">
                      <h4>
                        {" "}
                        <strong>Time: </strong>
                        {item.created_datetime}
                      </h4>
                    </div>
                  </div>
                  ----------------------------------
                  ----------------------------------
                  ---------------------------------- --------------------
                  {/* Counter  */}
                  <div className="price-total">
                    <div className="title">
                      <h3>
                        {" "}
                         <strong>Title: </strong>
                        {item.title}
                      </h3>
                      <div className="counter">
                      <strong><Display message={counter}/>x</strong>
                      </div>
                    </div>
  
                    <div className="increase">
                    <button onClick={() => setCounter(counter + 1)}>+</button>
                      
                    </div>
                    <div className="decrease">
                    <button onClick={() => setCounter(counter - 1)}>-</button>
                    </div>
  
                    {/* Price and total */}
  
                    <div className="price">
                      <h4>
                        <strong>Price: {parseFloat(item.price)}$</strong>
                      </h4>
                    </div>
  
                    <div className="total">
                      
                      <h4>
                      Total: {parseFloat(item.price*counter)}$
                      </h4>
                    </div>
                  </div>
                  
                </React.Fragment>
              ))}
          </div>
        </div>
  
        <div className="button-path">
          <Link to="/">
            <div className="button">
              <button className="main-button">Analyse Receipt</button>
            </div>
          </Link>
        </div>
  
        <Switch>
          <Route path="/bills/:id" /> 
        </Switch>
        <div>ID: {params.id}</div>
  
        
      </div>
    );
  
  }
  


const mapStateToProps = (state) => {
  return {
    items: state.items,
  };
};

const mapDispatchToProps = (dispatch) => {
  return {
    getItems: () => dispatch(getItems()),
  };
};

export default connect(mapStateToProps, mapDispatchToProps)(BillList);

Upvotes: 0

Views: 1497

Answers (2)

lmonninger
lmonninger

Reputation: 961

You will need to store the total price in some kind of state:


const [totalPrice, setTotalPrice] = useState(0);

You will then be able to update the total price by either...

  1. returning the desired summation from that UpdateTotalPrice function and wrapping it in a setTotalPrice:
setTotalPrice(UpdateTotalPrice(event));
  1. Or, using setTotalPrice therein.

Once you have that, you can use that setTotalPrice logic in some kind of event handler.

const handleClick = ()=>{
   // total price update logic
}

It looks like you may want UpdateTotalPrice to be that handler, which works just as well. But, whatever the handler may be, you then need to pass it as the onClick prop for your Buttons.

onClick={handleClick}

Couple additional notes:

  1. You are mixing imperative Javascript with React. You'll have an easier time if you conform to React's (generally) declarative style. This post might help.
  2. Use const instead of let or var.

Edit: Sorry, it looks like you would like to be using redux to manage your state. In that case, you will need make use of your dispatch and a useSelector. The pattern remains the same though.

Upvotes: 1

Tales Bontempo Cunha
Tales Bontempo Cunha

Reputation: 51

Did you try that? I can't see why it wouldn't work

Total: {parseFloat(item.price*counter)}$

Extract your item to a component:

function Item({item}) {
    const [counter, setCounter] = useState(1)
    return (
        <div>
           ...
           <Button onClick={() => setCounter(counter + 1)}>+</Button>
           <Button onClick={() => setCounter(counter - 1)}>-</Button>
           ...
           Total: {parseFloat(item.price*counter)}$
           ...
        </div>
    )
}

Upvotes: 1

Related Questions