如何在REACT JS中保持先前更改的状态,因为更新新项目时,previous设置为default?

问题描述 投票:2回答:3

我有一个购物车在反应(不使用Redux),每个项目前面有数量输入字段。对于所有人来说,数量默认为1。每个项目的TotalPrice都是它的含义(unitPrice * 1)。现在,如果用户更新Qty值,则需要更新TotalPrice(unitPrice * Qty)。我的代码正在这样做,但问题是当我更新一个项目数量时,它更新价格,很好,但当我更新另一个项目数量时,之前更新的价格将重置为默认值(返回到UnitPrice)。

我搜索了很多但没有用。大多数人使用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>  ); }
}
javascript reactjs mapping state shopping-cart
3个回答
0
投票

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

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方法应该找到所选产品并更新其数量,并且totalPrice:

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

0
投票

我认为您的问题是您管理cartItems的方式。在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})
}

0
投票

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

编辑:

现在你可以尝试渲染我称之为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.Item与你的父组件通信的东西

© www.soinside.com 2019 - 2024. All rights reserved.