3

I'm an extremely new user to React and I'm having trouble with an app I'm trying to design. Basically I want a list of products that I can have the user update a quantity of, the total for each quantity will appear under the product and the total for the whole package will appear at the bottom. If anyone can help me with this it would be very much appreciated. My code is included below `

import React, { Component } from "react";
import logo from "./logo.svg";
import "./App.css";

class App extends Component {


  render() {
    /* This is the Counter Part of the App used to denote the quantity of items*/
     class Counter extends React.Component {
      constructor(props) {
        super(props);

        this.state = {
          count: 0
        };
      }

      onUpdate = (val) => {
        this.setState({
          count: val
        });
      };

      render() {

        return (
          <div>
            <CounterChild onUpdate={this.onUpdate} />
            <br />
            <OtherChild passedVal={this.state.count} />
          </div>
        )
      }
    }
    /*Counter Section Ends here*/

    class CounterChild extends Component {
      constructor(props) {
        super(props);

        this.state = {
          count: 0 // Setting the Original State
        };
      }

      increase = e => {
        this.props.onUpdate(e.target.value  = (this.state.count + 1)) // Passed to Other child and Parent
        this.setState({count: this.state.count + 1}); // Setting the New State
      };

      decrease = e => {
        this.props.onUpdate(e.target.value  = (this.state.count - 1))
        this.setState({count: this.state.count - 1});
      };

      render() {
        return (
          <div>
            {this.state.count}<br />
            <button onClick={this.decrease.bind(this)}>-</button>
            <button onClick={this.increase.bind(this)}>+</button>
          </div>
        );
      }
    }

    /* The following is used to load the products list*/
    var products = [["product one", 24.99], ["product two", 9.99]];
    /* products list ends*/

    class OtherChild extends React.Component {
      render() {          
        return (
          <div>
            {this.props.passedVal}
          </div>
        );
      }
    }

    /* This is the section of the app which calculates the price times the quantity*/

    /*Price Section Ends here*/


    /*This section is used to calculate the total that appears at the bottom of the page*/
    var myTotal = 0; // Variable to hold your total

    for (var i = 0, len = products.length; i < len; i++) {
      myTotal += products[i][1]; // Iterate over your first array and then grab the second element add the values up
    }
    /*Total calculation section ends*/


    var productPrice = 0; // Variable to hold your total

    for (var q = 0, pricelen = products.length; q < pricelen; q++) {
      productPrice = products[q][1]; // Iterate over your first array and then grab the second element add the values up
    }




    /*The following section displays the product info in the app one line at a time*/
    class Test extends Component {
      render() {
        var productComponents = this.props.products.map(function(product) {

          return (
            <div className="product">
              {product[0]}<br />
              £{productPrice}<br />
              <Counter />
            </div>
          );
        });
        return <div>
        {productComponents}
        </div>;
      }

    }
    /*Product info display Ends*/

    /*The following section returnd the final output which appears on screen*/
    return (
      <div className="App">
        <div className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h2>Welcome to React</h2>
        </div>
        <div>
          <Test products={products} />
          £{myTotal}
        </div>

      </div>
    );
  }
}

export default App;

` I apologise if the code is messy, as I said I'm very new at this. Any assistance would be greatly appreciated

1 Answer 1

14

Checkout the snippet below, I think it should help.

class App extends React.Component {
  state = {
    products: [
      {title: 'Apple', count: 0, price: 100},
      {title: 'IBM', count: 0, price: 200},
      {title: 'HP', count: 0, price: 300},
    ]
  }
  
  onChange = (index, val) => {
    this.setState({
      products: this.state.products.map((product, i) => (
        i === index ? {...product, count: val} : product
      ))
    })
  }

  render () {
    return (
      <div>
        <ProductList products={this.state.products} onChange={this.onChange} />
        <Total products={this.state.products} />
      </div>
    )
  }
};

const ProductList = ({ products, onChange }) => (
  <ul>
    {products.map((product, i) => (
      <li key={i}>
        {product.title}
        <input 
          type="text" 
          value={product.count}
          onChange={e => onChange(i, parseInt(e.target.value) || 0)}
        />
      </li>
    ))}
  </ul>
);

const Total = ({ products }) => (
  <h3>
    Price: 
    {products.reduce((sum, i) => (
      sum += i.count * i.price
    ), 0)}
  </h3>
)


ReactDOM.render(<App />, document.querySelector('#root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks, that looks good, is there any way to limit the Total output to 2 decimal places?
yep, here is the top answer stackoverflow.com/a/6134070/3914350
Thanks for the answer, I was looking for this line, {products.reduce((sum, i) => ( sum += i.count * i.price ), 0)}
@Ivan Burnaev totally saved my ass ! Spasibo, Chuvak !

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.