3
votes

Comment conserver l'état modifié précédent dans REACT JS comme lorsque le nouvel élément est mis à jour, le précédent est défini par défaut?

J'ai un panier dans react ( Ne pas utiliser Redux ) qui a un champ de saisie Quantité en face de chaque article. La Qté est 1 par défaut pour tous. TotalPrice pour chaque article est indiqué (unitPrice * 1). Désormais, si l'utilisateur met à jour la valeur Qty, TotalPrice doit être mis à jour (unitPrice * Qty). Mon code le fait, mais le problème est lorsque je mets à jour une quantité d'article, il met à jour le prix, très bien, mais lorsque je mets à jour une autre quantité d'article, le prix précédemment mis à jour est réinitialisé par défaut (retour à UnitPrice).

J'ai beaucoup cherché mais pas utile. La plupart des gens utilisent redux mais je ne veux pas l'utiliser. Alors s'il vous plaît, aidez-moi si vous voyez une solution car je souhaite maintenir tous les prix mis à jour.

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


0 commentaires

3 Réponses :


0
votes

Vous utilisez le même état pour différent pour chaque article, donc chaque changement que vous apportez à la quantité modifiera votre état et donc le prix de l'article de tout. il n'est pas nécessaire d'utiliser redux pour cela. Vous pouvez faire deux choses: déplacer la logique de l'article vers un sous-composant, ainsi, chaque article aura son propre état, ou, modifier votre état pour gérer un tableau d'objets comme {name: 'itemname', price: itemPrice etc. etc. que j'ai appelé ChartItem, ils recevront {... item} le vous pouvez. utilisez depuis l'intérieur de votre composant via this.props.yourItemProp

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

Maintenant, dans chaque ChartItem, vous pouvez définir un état privé et l'utiliser. Si vous voulez communiquer avec le composant parent, passez simplement au compone enfant une fonction telle que

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

/>}

donc, vous pouvez l'appeler. props.onItem Quelque chose à communiquer avec votre composant parent


2 commentaires

Merci beaucoup pour la réponse. J'ai mis à jour mon cartItems [] et maintenant chaque article a une quantité = 1 avec lui. Maintenant, pourriez-vous expliquer comment déplacer ma logique vers un sous-composant? Dois-je passer un ID et un accessoire de quantité dans le sous-composant où il calculerait totalPrice en fonction de la quantité mise à jour? Je serais très reconnaissant de votre aide.


@YellowMinion a édité mu ansewer, j'espère que cela vous aidera



0
votes

Ce que vous devez faire est, lorsque vous recevez les articles de votre panier, de parcourir chaque article et d'ajouter une quantité pour chacun d'entre eux. Et ajoutez un total en état pour le total de tous les produits.

this.state.cartItems.forEach(item => {
    console.log(item.total);
})

La méthode OnChange devrait trouver le produit sélectionné et mettre à jour sa quantité, ainsi que le totalPrice:

{this.state.totalPrice}


7 commentaires

Merci beaucoup pour la réponse. Je pense que vous vouliez dire dans htm que je peux montrer par {this.state.totalPrice}, essayé comme vous l'avez dit, mais il met maintenant à jour le prix pour tous les produits même si je mets à jour la quantité pour un produit spécifique.


@YellowMinion oui désolé, je l'ai mal tapé dans la méthode onchange, dans le setState je l'ai tapé total au lieu de totalPrice. J'ai mis à jour le code et revérifier si vous le pouvez. Alors laissez-moi savoir si cela fonctionne


Oui, j'ai compris que c'était une faute de frappe donc j'avais déjà mis à jour "total" en "totalPrice". Mais il met à jour TotalPrice par rapport à tous les produits au lieu de celui-là spécifique. Je pense que son réglage est le même état de totalPrice pour tous.


@YellowMinion le vérifie maintenant. J'ai ajouté le total à chaque produit lorsque vous obtenez pour la première fois d'axios. Et puis mettez à jour le total de chaque élément sur l'événement onChage, puis à la fin, il vous montre comment vous pouvez l'obtenir


Désolé de déranger à nouveau. J'ai fait de même et cela montre une erreur sur cette ligne const item = item.items.find (item => item.id === sid); Erreur disant que typeError: Impossible de lire la propriété ' éléments "non définis


@YellowMinion désolé mon mal, ça devrait être items.find () ... pas item.items.find () ... .


Merci beaucoup. Ça a marché. J'apprécie vraiment votre réponse et votre aide. Dieu vous bénisse.



0
votes

Je pense que votre problème est la façon dont vous gérez vos articles de panier. Dans onChangeQty, vous devez parcourir votre this.state.cartItems et trouver l'élément avec le sid sélectionné, vous pouvez utiliser

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 commentaires