اذهب إلى المحتوى
  • 0

إضافة و تنقيص عنصر محدد باستخدام رياكت هوكس

محمود_سعداوي

السؤال

السلام عليكم.

Capture.JPG.4a5f4bf2c7baf0c873da3daf671f1a67.JPG

مثلما توضح الصورة  عند النقر على + يضاف 1 و كذلك بالنسبة ل-

المشكل أنه عند النقر على زر واحدة تتغير كافة العناصر الأخرى.

الكود

import React,{useState} from 'react'

function Cart({cartItems, setModal, removeFromCart, addToCart}) {
  let [qty, setQty] = useState(1)
 
  return (
    <div className='cart-modal'>
      {
        cartItems.length === 0 ? <h1 className='empty-cart'>Your Cart Is Empty</h1>
        : cartItems.map((cartItem,index) => (
            <div className="cart-product" key={index}>
                <img src={cartItem.image} alt="" srcSet="" />
                <div className="cart-product-info">
                  <h3 className='cart-price'>{cartItem.price}$</h3>
                  <div className="quantity">
                    <button 
                      type='button' 
                      className='plus'
                      onClick={()=>setQty(qty++)}
                    >+</button>
                    <h4 className='qty'>{qty}</h4>
                    <button 
                      type='button' 
                      className='minus'
                      disabled={cartItem.qty <= 1}
                      onClick={()=>setQty(qty --)}
                    >-</button>
                    <button type='button' className='remove'>
                      <i className="fa-solid fa-trash"
                        onClick={()=>removeFromCart(cartItem.id)}></i>
                    </button>
                  </div>
                  <h2 className='total'>{cartItem.price * qty}</h2>
                </div>     
            </div>
        ))
      }
      <div className="cart-summary">
        <h2 className='cart-summary-title'>Total: {}$</h2>
        <button type='button' onClick={()=>setModal(false)}>CLOSE</button>
      </div>
    </div>
  )
}

export default Cart

 

رابط هذا التعليق
شارك على الشبكات الإجتماعية

Recommended Posts

  • 0

المشكلة تحدث لأن كل العناصر تتحكم في نفس الحالة qty.

لحل المشكلة جرب تعديل الكود للشكل التالي، حيث ننشئ مكون جديد خاص بالعنصر الداخل ونضيف حالة qty لكل عنصر على حدى  :

 

import React,{useState} from 'react'

function Cart({cartItems, setModal, removeFromCart, addToCart}) {
  return (
    <div className='cart-modal'>
      {
        cartItems.length === 0 ? <h1 className='empty-cart'>Your Cart Is Empty</h1>
        : cartItems.map((cartItem,index) => (   <ItemComponent cartItem={cartItem} key={index} />))
      }
      <div className="cart-summary">
        <h2 className='cart-summary-title'>Total: {}$</h2>
        <button type='button' onClick={()=>setModal(false)}>CLOSE</button>
      </div>
    </div>
  )
}
const ItemComponent = ({cartItem , removeFromCart})=>{
  let [qty, setQty] = useState(1)
  return(
   <div className="cart-product">
                  <img src={cartItem.image} alt="" srcSet="" />
                  <div className="cart-product-info">
                    <h3 className='cart-price'>{cartItem.price}$</h3>
                    <div className="quantity">
                      <button 
                        type='button' 
                        className='plus'
                        onClick={()=>setQty(qty++)}
                      >+</button>
                      <h4 className='qty'>{qty}</h4>
                      <button 
                        type='button' 
                        className='minus'
                        disabled={cartItem.qty <= 1}
                        onClick={()=>setQty(qty --)}
                      >-</button>
                      <button type='button' className='remove'>
                        <i className="fa-solid fa-trash"
                          onClick={()=>removeFromCart(cartItem.id)}></i>
                      </button>
                    </div>
                    <h2 className='total'>{cartItem.price * qty}</h2>
                  </div>     
              </div>
  )
}
export default Cart
رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 0

المشكلة تحدث بسبب استخدام useState بطريقة خاطئة. في هذا الكود ، تم استخدام حالة qty المحلية لجميع العناصر في cartItems. لذلك ، عند تحديث qty لأي من العناصر ، ستتأثر جميع العناصر الأخرى بقيمة qty الجديدة.

لحل هذه المشكلة ، يمكنك استخدام حالة qty المحلية لكل عنصر على حدة. يمكنك تحقيق ذلك عن طريق تحويل qty إلى مصفوفة من القيم في حالة useState وتخزين القيم بناءً على معرف العنصر.

إليك الكود المعدل:

import React, { useState } from 'react'

function calculateTotal(cartItems) {
  let total = 0;
  for (let i = 0; i < cartItems.length; i++) {
    const price = parseInt(cartItems[i].price);
    const qty = cartItems[i].qty;
    if (!isNaN(price)) {
      total += price * qty;
    }
  }
  return total;
}

function Cart({ cartItems, setModal, removeFromCart, addToCart }) {
  const [qtyArray, setQtyArray] = useState(
    cartItems.map((cartItem) => ({ id: cartItem.id, qty: 1 }))
  )

  const handlePlus = (index) => {
    setQtyArray((prevState) =>
      prevState.map((item, idx) =>
        idx === index ? { ...item, qty: item.qty + 1 } : item
      )
    )
  }

  const handleMinus = (index) => {
    setQtyArray((prevState) =>
      prevState.map((item, idx) =>
        idx === index ? { ...item, qty: item.qty - 1 } : item
      )
    )
  }

  return (
    <div className='cart-modal'>
      {cartItems.length === 0 ? (
        <h1 className='empty-cart'>Your Cart Is Empty</h1>
      ) : (
        cartItems.map((cartItem, index) => {
          const qtyIndex = qtyArray.findIndex(
            (item) => item.id === cartItem.id
          )
          const qty = qtyArray[qtyIndex].qty
          return (
            <div className='cart-product' key={index}>
              <img src={cartItem.image} alt='' />
              <div className='cart-product-info'>
                <h3 className='cart-price'>{cartItem.price}$</h3>
                <div className='quantity'>
                  <button
                    type='button'
                    className='plus'
                    onClick={() => handlePlus(qtyIndex)}
                  >
                    +
                  </button>
                  <h4 className='qty'>{qty}</h4>
                  <button
                    type='button'
                    className='minus'
                    disabled={cartItem.qty <= 1}
                    onClick={() => handleMinus(qtyIndex)}
                  >
                    -
                  </button>
                  <button type='button' className='remove'>
                    <i
                      className='fa-solid fa-trash'
                      onClick={() => removeFromCart(cartItem.id)}
                    ></i>
                  </button>
                </div>
                <h2 className='total'>{cartItem.price * qty}</h2>
              </div>
            </div>
          )
        })
      )}
      <div className='cart-summary'>
        <h2className='cart-summary-title'>Total: {calculateTotal(cartItems)}$</h2>
<button type='button' onClick={()=>setModal(false)}>CLOSE</button>
</div>
</div>
)
}
export default Cart

 

تم التعديل في بواسطة Mustafa Suleiman
تصحيح خطأ في الكود
رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 0
بتاريخ 4 ساعة قال Mustafa Suleiman:
calculateTotal(cartItems)}

شكرا لكم

لكن يوجد bug هنا حيث أنه ترجع القيمة NaN

حاولت التعديل بإضافة parseInt لكن لاشيء تغير.

 

رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 0
بتاريخ 30 دقائق مضت قال محمود سعداوي:

شكرا لكم

لكن يوجد bug هنا حيث أنه ترجع القيمة NaN

حاولت التعديل بإضافة parseInt لكن لاشيء تغير.

بالنسبة للكود الذي قمت بتوفيره، يمكنك التحقيق من طريقة الحساب الذي يتم فيه ضرب سعر العنصر في الكمية، لأن القيمة التي ترجعها الدالة calculateTotal هي NaN، وذلك لأن قيمة الـ price غير محددة بشكل صحيح.

لتصحيح هذا الخطأ، يجب التحقق من قيمة الـ price في كل عنصر من cartItems والتأكد من أنها رقم صحيح، وإذا كانت غير ذلك يتم تعديلها لتكون رقم صحيح. يمكن استخدام الدالة parseInt() لتحويل القيمة إلى رقم صحيح. وباستطاعتك استخدام الكود التالي:

function calculateTotal(cartItems) {
  let total = 0;
  for (let i = 0; i < cartItems.length; i++) {
    const price = parseInt(cartItems[i].price);
    const qty = cartItems[i].qty;
    if (!isNaN(price)) {
      total += price * qty;
    }
  }
  return total;
}

حيث تم استخدام parseInt() لتحويل قيمة الـ price إلى رقم صحيح، والتحقق من أنها رقم صحيح باستخدام isNaN() قبل القيام بعملية الضرب.

رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 0
بتاريخ On 16‏/3‏/2023 at 21:44 قال Mustafa Suleiman:

بالنسبة للكود الذي قمت بتوفيره، يمكنك التحقيق من طريقة الحساب الذي يتم فيه ضرب سعر العنصر في الكمية، لأن القيمة التي ترجعها الدالة calculateTotal هي NaN، وذلك لأن قيمة الـ price غير محددة بشكل صحيح.

لتصحيح هذا الخطأ، يجب التحقق من قيمة الـ price في كل عنصر من cartItems والتأكد من أنها رقم صحيح، وإذا كانت غير ذلك يتم تعديلها لتكون رقم صحيح. يمكن استخدام الدالة parseInt() لتحويل القيمة إلى رقم صحيح. وباستطاعتك استخدام الكود التالي:

function calculateTotal(cartItems) {
  let total = 0;
  for (let i = 0; i < cartItems.length; i++) {
    const price = parseInt(cartItems[i].price);
    const qty = cartItems[i].qty;
    if (!isNaN(price)) {
      total += price * qty;
    }
  }
  return total;
}

حيث تم استخدام parseInt() لتحويل قيمة الـ price إلى رقم صحيح، والتحقق من أنها رقم صحيح باستخدام isNaN() قبل القيام بعملية الضرب.

السلام عليكم.

أعتذر على كل هذه الأسئلة.

نفس المشكل أخي يقع إرجاع القيمة NaN مجددا.

حاولت تفهدي الأمر بوضع qtyArray عوضا عن cartItems لكن في هذه الحالة لا يقع تحديث للمبلغ الجملي عند حذف منتج

الكود كاملا للإطلاع.

import React, { useState } from 'react'

function calculateTotal(cartItems) {
  let total = 0;
  for (let i = 0; i < cartItems.length; i++) {
    const price = parseInt(cartItems[i].price);
    const qty = cartItems[i].qty;
    total += price * qty;
  }
  return total;
}

function Cart({ cartItems, setModal, removeFromCart }) {
  const [qtyArray, setQtyArray] = useState(
    cartItems.map((cartItem) => ({ ...cartItem, qty: 1 }))
  )
  const handlePlus = (index) => {
    setQtyArray((prevState) =>
      prevState.map((item, idx) =>
        idx === index ? { ...item, qty: item.qty + 1 } : item
      )
    )
  }

  const handleMinus = (index) => {
    setQtyArray((prevState) =>
      prevState.map((item, idx) =>
        idx === index ? { ...item, qty: item.qty - 1 } : item
      )
    )
  }

  return (
    <div className='cart-modal'>
      {cartItems.length === 0 ? (
        <h1 className='empty-cart'>Your Cart Is Empty</h1>
      ) : (
        cartItems.map((cartItem, index) => {
          const qtyIndex = qtyArray.findIndex(
            (item) => item.id === cartItem.id
          )
          const qty = qtyArray[qtyIndex].qty
          return (
            <div className='cart-product' key={index}>
              <img src={cartItem.image} alt='' />
              <div className='cart-product-info'>
                <h3 className='cart-price'>{cartItem.price}$</h3>
                <div className='quantity'>
                  <button
                    type='button'
                    className='plus'
                    onClick={() => handlePlus(qtyIndex)}
                  >
                    +
                  </button>
                  <h4 className='qty'>{qty}</h4>
                  <button
                    type='button'
                    className='minus'
                    disabled={qty <= 1}
                    onClick={() => handleMinus(qtyIndex)}
                  >
                    -
                  </button>
                  <button type='button' className='remove'>
                    <i
                      className='fa-solid fa-trash'
                      onClick={() => removeFromCart(cartItem.id)}
                    ></i>
                  </button>
                </div>
                <h2 className='total'>{cartItem.price * qty}</h2>
              </div>
            </div>
          )
        })
      )}
      <div className='cart-summary'>
      <h2 className='cart-summary-title'>Total: {calculateTotal(cartItems)}$</h2>
<button type='button' onClick={()=>setModal(false)}>CLOSE</button>
</div>
</div>
)
}
export default Cart

شكرا

رابط هذا التعليق
شارك على الشبكات الإجتماعية

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...