0

I am having problems with the total number of items in the CartHeader component. Obviously I have added the quantity of each product but the result is not as I expected ?. Can someone find the fault for me? I sincerely thank.

import ReactDOM from "react-dom";
import CartHeader from "./CartHeader";
import CartBody from "./CartBody";
import CartFooter from "./CartFooter";
import "./styles.css";

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      products: [
        {
          id: 1,
          name: "Apple Watch Series 5",
          description: "Description for Apple Watch Series 5",
          img:
            "https://bachlongmobile.com/media/catalog/product/cache/2/image/040ec09b1e35df139433887a97daa66f/2/0/2076130625_1_1_1.jpg",
          price: 499.99,
          quantity: 1
        },
        {
          id: 2,
          name: "iPhone 11 Pro Max",
          description: "Description for iPhone 11 Pro Max",
          img:
            "https://cdn.fptshop.com.vn/Uploads/Originals/2019/9/11/637037687763926758_11-pro-max-xanh.png",
          price: 1099.99,
          quantity: 1
        },
        {
          id: 3,
          name: "Macbook Pro 16 inch",
          description: "Description for Macbook Pro 16 inch",
          img: "https://shopdunk.com/wp-content/uploads/2019/11/mac16inch.jpg",
          price: 2399.99,
          quantity: 1
        },
        {
          id: 4,
          name: "iPad Pro 12.9 inch",
          description: "Description for iPad Pro",
          img:
            "https://cdn.fptshop.com.vn/Uploads/Originals/2019/1/11/636828015979564724_ipad-pro-12-9-xam-1.png",
          price: 999.99,
          quantity: 1
        },
        {
          id: 5,
          name: "AirPods Pro",
          description: "Description for AirPods Pro",
          img:
            "https://store.storeimages.cdn-apple.com/4982/as-images.apple.com/is/MWP22?wid=1144&hei=1144&fmt=jpeg&qlt=80&op_usm=0.5,0.5&.v=1572990352299",
          price: 249.99,
          quantity: 1
        }
      ]
    };
  }

  onRemoveProduct = id => {
    const newProducts = this.state.products;
    // Tìm vị trí sản phẩm cần xoá
    let index = newProducts.findIndex(product => product.id === id);
    // Kiểm tra nếu tìm thấy thì mới xoá
    if (index !== -1) {
      newProducts.splice(index, 1);
      this.setState({
        products: newProducts
      });
    }
  };

  handleChange = (e, id) => {
    const { products } = this.state;
    const indexProduct = products.findIndex(product => product.id === id);
    products[indexProduct].quantity = e.target.value;
    this.setState({ products });
  };

  render() {
    const products = this.state.products;
    let numberItems = 0;
    let subTotal = 0;
    products.map(product => {
      numberItems += product.quantity;
      subTotal += product.price * product.quantity;
    });

    return (
      <main>
        <CartHeader numberItems={numberItems} />
        <CartBody
          products={products}
          onRemoveProduct={this.onRemoveProduct}
          handleChange={this.handleChange}
        />
        <CartFooter subTotal={subTotal} />
      </main>
    );
  }
}

export default App;

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

have I ever misunderstood the problem. Link codesandbox: https://codesandbox.io/s/thirsty-hill-6w2ex

2
  • Please provide how you tried to solve this problem and why you was not succeded, this question looks more like task rather than question Commented Jan 6, 2020 at 8:02
  • @DmitryReutov thank you for comment. I have learned and fixed this problem Commented Jan 6, 2020 at 14:56

2 Answers 2

1

You should define curry function for handleChange method like below:

  handleChange = id => e => {
    const {products} =  this.state;
    const indexProduct = products.findIndex(product => product.id === id);
    products[indexProduct].quantity = e.target.value;
    this.setState({ products: [...products] });
  };

inside CardBody:

  <input
      type="number"
      className="quantity"
      step={1}
      defaultValue={product.quantity}
      onChange={e => handleChange(product.id)(e)}
      />

Here you can find codesandbox

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

19 Comments

Nearly identical to my solution. One suggestion, shallow copy this.state.products array to mutate and return. Don't mutate and return existing array, this can lead to render issues.
nice catch @DrewReese. fixed.
products is an array, not an object. this.setState({ products: [...products] }); Though I usually prefer to copy first, then mutate the copy.
Why curry when you can just pass the id as another parameter? handleChange(e, id) => ...
@DrewReese is still working with {...products} any thought?
|
0

Dynamic data display is best accomplished through the React state. At the moment, you define variables within the render() function, but this area is largely for static data.

First, define the numerical values (quantity and total) as state values instead of variables. Then, define a function that handles the onChange event of each quantity input for each product. In that function, handle the accumulation of each numerical value and subsequently update the state with those values.

Comments

Your Answer

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