如何在更新新项目时将REACT JS中的先前更改状态保持为默认状态?

时间:2019-04-10 08:05:42

标签: javascript reactjs mapping state shopping-cart

我有一个购物车中有反应 未使用Redux ),其中每个项目前面都有“数量”输入字段。默认情况下,数量为1。每个项目的总价格是该项目的信息(单价* 1)。现在,如果用户更新“数量”值,则需要更新(单价*数量)。我的代码正在执行此操作,但是问题是当我更新一个项目的数量时,它会更新价格,很好,但是当我更新另一个项目的数量时,先前更新的价格将重置为默认值 (返回单价)。

我搜索了很多但没有用。大多数人都使用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>  ); }
}

3 个答案:

答案 0 :(得分:0)

您对每件商品都使用相同的状态,因此对数量所做的每一次更改都会修改您的状态,因此每件商品的商品价格都会改变。无需为此使用redux。您可以做两件事:将项目逻辑移至子组件,因此,每个项目都将具有自己的状态,或者通过修改状态来处理诸如{name:'itemname', price:itemPrice etc etc}之类的对象数组,只需编辑一个特定商品或改善您的购物车商品:[]数量多。

编辑:

现在您可以尝试渲染n个我称为ChartItem的子组件,它们将收到{...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与您的父组件进行通讯

答案 1 :(得分:0)

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

答案 2 :(得分:-1)

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

    public static function getCategoryList()
    {

        $db = Db::getConnection();

        $lang = self::Language();

        $categoryList = [];

        $result = $db->query("SELECT content.id, content.title$lang,content.slug$lang, content.sub_category_id, category.slug$lang FROM blog_category AS content LEFT JOIN blog_category AS category ON content.sub_category_id = category.id WHERE content.status='1' ORDER BY content.sort_order ASC");

        foreach($result as $row){
            $categoryList[] = [
                'id' => $row[0],
                'title' => $row[1],
                'slug' => $row[2],
                'sub_category' => $row[4],
            ];
        }
        return $categoryList;

    }

OnChange方法应找到所选产品并更新其数量和totalPrice:

    <?php foreach ($category as $categoryItem): ?>
        <h4><a href="/blog/<?php if ($categoryItem['sub_category']) echo $categoryItem['sub_category'] . '/'; ?><?php echo $categoryItem['slug']; ?>"><?php echo $categoryItem['title']; ?></a></h4>
        <p><?php echo $categoryItem['id']; ?></p>
    <?php endforeach; ?>

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

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

}

如果您想总计每个项目,则只需按以下方式进行检查即可:

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

}
相关问题