Как сохранить предыдущее измененное состояние в REACT JS, так как при обновлении нового элемента предыдущий устанавливается по умолчанию? - PullRequest
3 голосов
/ 10 апреля 2019

У меня есть корзина для покупок в реакции ( Не используется Redux ), в котором поле Количество вводится перед каждым элементом. Кол-во равно 1 по умолчанию для всех. TotalPrice для каждого элемента информируется об этом (unitPrice * 1). Теперь, если пользователь обновляет значение Qty, TotalPrice должен быть updated (unitPrice * Qty). Мой код делает это, но проблема - это когда я обновляю один элемент Кол-во, он обновляет цену, отлично, но когда я обновляю другой элемент Кол-во, ранее обновленная цена сбрасывается до значения по умолчанию (назад в UnitPrice).

Я искал это много, но бесполезно. Большинство людей используют излишки, но я не хочу их использовать. Поэтому, пожалуйста, помогите мне, если вы увидите решение для этого , поскольку я хочу сохранить все обновленные цены.

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 голосов
/ 10 апреля 2019

Что вам нужно сделать, так это, когда вы получите товары из своей корзины, просмотреть каждый товар и добавить количество для каждого из них.И добавьте итоговое значение в состоянии для общей суммы всех продуктов.

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 голосов
/ 10 апреля 2019

Я думаю, что ваша проблема в том, как вы управляете своими 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 голосов
/ 10 апреля 2019

Вы используете одно и то же состояние для разных товаров, поэтому каждое изменение количества влияет на ваше состояние и, следовательно, на цену товара.для этого нет необходимости использовать излишки.Вы можете сделать две вещи: переместить логику элемента в подкомпонент, чтобы у каждого элемента было свое собственное состояние, или изменить свое состояние, чтобы обрабатывать массив объектов, таких как {name:'itemname', price:itemPrice etc etc}, таким образом, вы будете редактировать только конкретный элемент.или улучшите свои cartItems: [] с помощью кол-во.

РЕДАКТИРОВАТЬ:

теперь вы можете попытаться отобразить 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, чтобы связаться с вашимродительский компонент

...