当更新新项目时,如何在 REACT JS 中保持先前更改的状态,先前设置为默认值?

How to maintain previous changed state in REACT JS as when new item is updated, previous is set to default?

我有一个 react 中的购物车(不使用 Redux)它有数量每个项目前面的输入字段。 Qty 默认为 1。 TotalPrice 每件商品均已告知(单价*1)。现在,如果用户更新 Qty 值,TotalPrice 需要 updated(unitPrice*Qty)。我的代码正在这样做,但是 问题 是当我更新一个项目数量时,它会更新价格,很好,但是当我更新另一个项目数量时, 之前更新的价格被重置为默认(回到单价)。

我找了很多都没有用。大多数人使用 redux 但我不想使用它。因此,如果您看到解决方案,请帮助我,因为我想保持所有更新的价格。

export default class Cart extends Component
{
  constructor(props) {
      super(props);

      this.state = {
        data:[],
        customer: '',
        redirectToReferrer: false,
        cart: [],
        cartItems: [],
        
        qty: '',
        clicked: ''      };
 this.onChangeQty = this.onChangeQty.bind(this);
}

componentDidMount() {
 
    const retrieved = localStorage.getItem("cartItem");
    const arr = JSON.parse(retrieved);
    axios.post('http://localhost/Auth/api/customers/show_cart.php', arr,
     {
    headers: {'Accept': 'application/json, text/plain, */*',
              'Content-Type': 'application/json'}
    } )
    .then(response => {
    this.setState({
             cartItems :response.data.records
           });
      })
     .catch(error => {
     if (error) {
       console.log("Error");  }
       });

}


onChangeQty(sid,e)
{
this.setState({
  clicked: sid,
  qty: e.target.value })

}

  render()
  {
    return (
<div id="profileDiv">

<Col md="12" lg="12" sm="12" xs="12">
<h1> <b> Your Shopping Cart </b>  </h1>

<Table>
<thead>
    <tr className="text-center">

        <th> Item# </th>
        <th> Image </th>
        <th> ID</th>
        <th> Name</th>
        <th> Unit Price </th>
        <th> Quantity </th>
        <th> Total Price </th>

    </tr>
</thead>

<tbody>
{this.state.cartItems.map( (item, i) =>

  <tr>

    <td className="text-center">
      <h4 key={i}> {i}</h4>
    </td>

    <td className="text-center">
    <Image src={"data:image/png[jpg];base64," +  item.Image}
     id="cartImage" alt="abc" />
    </td>

    <td className="text-center">
      <h4>{item.SparePartID}</h4>
    </td>

    <td className="text-center">
      <h4> {item.Name}</h4>
    </td>

    <td className="text-center">
      <h4 >{item.Price} </h4>
    </td>

    <td className="text-center">
      <h4 key={item.SparePartID}>
      <input className="text-center"
       type="number"
      min="1"
      onChange={(e) => this.onChangeQty(item.SparePartID, e)}
      />
      </h4>
    </td>

    <td className="text-center">
      <h4 key={item.SparePartID}>
      {
         this.state.clicked == item.SparePartID ?
         (item.Price*this.state.qty) : item.Price     
      }
      </h4>
    </td>

  </tr>

)}  </tbody>
</Table>
</Col>
</div>  ); }
}

您对每件商品都使用相同的状态,因此您对数量所做的每一次更改都会修改您的状态,因此也会修改所有商品的价格。没有必要为此使用 redux。您可以做两件事:将项目逻辑移动到子组件,这样,每个项目都有自己的状态,或者,修改您的状态以处理像 {name:'itemname', price:itemPrice etc etc} 这样的对象数组,这样您将只编辑一个特定项目或改进您的 cartItems: [] 与 qty 道具。

编辑:

现在您可以尝试呈现我称为 ChartItem 的 n 个子组件,它们将尽可能接收 {...item}。通过 this.props.yourItemProp

从组件内部使用
{this.state.cartItems.map( (item, i) => <ChartItem key={i} {...item} />}

现在,您可以在每个 ChartItem 中定义一个私有状态并使用它。如果你想与父组件通信,只需将函数传递给子组件,如

  {this.state.cartItems.map( (item, i) => <ChartItem key={i} {...item}
onItemSomething={this.handleOnItemSomething}

/>}

因此,您可以调用 this.props.onItemSomething 与您的父组件通信

您需要做的是,当您收到购物车商品时,检查每件商品并为每件商品添加数量。并为所有产品的总和添加状态总计。

constructor(props) {
      super(props);

      this.state = {
        data:[],
        customer: '',
        redirectToReferrer: false,
        cart: [],
        cartItems: [],
        totalPrice: 0
        clicked: ''      };
 this.onChangeQty = this.onChangeQty.bind(this);
}

componentDidMount() {

    const retrieved = localStorage.getItem("cartItem");
    const arr = JSON.parse(retrieved);
    axios.post('http://localhost/Auth/api/customers/show_cart.php', arr,
     {
    headers: {'Accept': 'application/json, text/plain, */*',
              'Content-Type': 'application/json'}
    } )
    .then(response => {
    let myItems = [];
    response.forEach(item => {
      myItems.push({id: item.id, name: item.name, qty: 1, price: item.price, total: item.price});
    })
    this.setState({
             cartItems :myItems
           });
      })
     .catch(error => {
     if (error) {
       console.log("Error");  }
       });

}

OnChange 方法应该找到所选产品并更新其数量,总价:

onChangeQty(sid,e)
{
  const items = this.state.cartItems;
  const item = items.find(item => item.id === sid);
  const index = items.indexOf(item);
  item.qty = e.target.value;
  item.total = item.qty * item.price;
  items[index] = index;

  let totalPrice = 0;
  items.forEach(item => {
      totalPrice += item.qty * item.price;
  });

  this.setState({
    cartItems: items,
    totalPrice
  });

}

并且在 html 中您可以将总价显示为

{this.state.totalPrice}

如果您想要每个项目的总数,您可以通过

简单地检查它
this.state.cartItems.forEach(item => {
    console.log(item.total);
})

我认为您的问题在于您管理购物车商品的方式。在 onChangeQty 你应该遍历你的 this.state.cartItems 并找到具有所选 sid 的项目,你可以使用

onChangeQty (sid, {target:{value}}){

    let {cartItems } = this.state
    let ind = cartItems.findIndex( o => o.sid === sid) //get index and 
                                                       //update the 
                                                       // qty of 
                                                       // that element of the cartItems 
                                                       // array , 
     cartItems[ind].sid + = value

    this.setState({cartItems})
}