如何在React中分配onChange事件时更新输入值?

huangapple go评论71阅读模式
英文:

How to update input value when assigning onChange event in React?

问题

我在CartHeader组件中有关购物车中物品总数的问题。显然,我已经添加了每个产品的数量,但结果不如我所预期的那样。有人可以帮我找到错误吗?我真诚地感谢。

import React from "react";
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: "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: "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英寸",
          description: "Macbook Pro 16英寸的描述",
          img: "https://shopdunk.com/wp-content/uploads/2019/11/mac16inch.jpg",
          price: 2399.99,
          quantity: 1
        },
        {
          id: 4,
          name: "iPad Pro 12.9英寸",
          description: "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: "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;
    // 找到需要移除的产品索引
    let index = newProducts.findIndex((product) => product.id === id);
    // 如果找到则移除
    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);

我是否曾经误解了这个问题。
链接到codesandbox:
https://codesandbox.io/s/thirsty-hill-6w2ex

英文:

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 &quot;react-dom&quot;;
import CartHeader from &quot;./CartHeader&quot;;
import CartBody from &quot;./CartBody&quot;;
import CartFooter from &quot;./CartFooter&quot;;
import &quot;./styles.css&quot;;
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
products: [
{
id: 1,
name: &quot;Apple Watch Series 5&quot;,
description: &quot;Description for Apple Watch Series 5&quot;,
img:
&quot;https://bachlongmobile.com/media/catalog/product/cache/2/image/040ec09b1e35df139433887a97daa66f/2/0/2076130625_1_1_1.jpg&quot;,
price: 499.99,
quantity: 1
},
{
id: 2,
name: &quot;iPhone 11 Pro Max&quot;,
description: &quot;Description for iPhone 11 Pro Max&quot;,
img:
&quot;https://cdn.fptshop.com.vn/Uploads/Originals/2019/9/11/637037687763926758_11-pro-max-xanh.png&quot;,
price: 1099.99,
quantity: 1
},
{
id: 3,
name: &quot;Macbook Pro 16 inch&quot;,
description: &quot;Description for Macbook Pro 16 inch&quot;,
img: &quot;https://shopdunk.com/wp-content/uploads/2019/11/mac16inch.jpg&quot;,
price: 2399.99,
quantity: 1
},
{
id: 4,
name: &quot;iPad Pro 12.9 inch&quot;,
description: &quot;Description for iPad Pro&quot;,
img:
&quot;https://cdn.fptshop.com.vn/Uploads/Originals/2019/1/11/636828015979564724_ipad-pro-12-9-xam-1.png&quot;,
price: 999.99,
quantity: 1
},
{
id: 5,
name: &quot;AirPods Pro&quot;,
description: &quot;Description for AirPods Pro&quot;,
img:
&quot;https://store.storeimages.cdn-apple.com/4982/as-images.apple.com/is/MWP22?wid=1144&amp;hei=1144&amp;fmt=jpeg&amp;qlt=80&amp;op_usm=0.5,0.5&amp;.v=1572990352299&quot;,
price: 249.99,
quantity: 1
}
]
};
}
onRemoveProduct = id =&gt; {
const newProducts = this.state.products;
// T&#236;m vị tr&#237; sản phẩm cần xo&#225;
let index = newProducts.findIndex(product =&gt; product.id === id);
// Kiểm tra nếu t&#236;m thấy th&#236; mới xo&#225;
if (index !== -1) {
newProducts.splice(index, 1);
this.setState({
products: newProducts
});
}
};
handleChange = (e, id) =&gt; {
const { products } = this.state;
const indexProduct = products.findIndex(product =&gt; 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 =&gt; {
numberItems += product.quantity;
subTotal += product.price * product.quantity;
});
return (
&lt;main&gt;
&lt;CartHeader numberItems={numberItems} /&gt;
&lt;CartBody
products={products}
onRemoveProduct={this.onRemoveProduct}
handleChange={this.handleChange}
/&gt;
&lt;CartFooter subTotal={subTotal} /&gt;
&lt;/main&gt;
);
}
}
export default App;
const rootElement = document.getElementById(&quot;root&quot;);
ReactDOM.render(&lt;App /&gt;, rootElement);

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

答案1

得分: 1

你应该像下面这样为handleChange方法定义curry函数:

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] });
};

在CardBody中:

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

你可以在CodeSandbox上找到示例代码。

英文:

You should define curry function for handleChange method like below:

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

inside CardBody:

  &lt;input
      type=&quot;number&quot;
      className=&quot;quantity&quot;
      step={1}
      defaultValue={product.quantity}
      onChange={e =&gt; handleChange(product.id)(e)}
      /&gt;

Here you can find codesandbox

答案2

得分: 0

动态数据显示最好通过React状态来实现。目前,您在render()函数内定义变量,但这个区域主要用于静态数据。

首先,将数量和总计的数值定义为状态值,而不是变量。然后,定义一个函数来处理每个产品的数量输入框的onChange事件。在该函数中,处理每个数值的累积,然后用这些值更新状态。

英文:

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.

huangapple
  • 本文由 发表于 2020年1月6日 15:57:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/59608525.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定