You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React电商购物车:从子组件获取价格并在父组件存入数组

解决方案

要实现子组件的价格同步到父组件的total数组,核心是通过父组件传递回调函数给子组件,子组件在价格变化时调用该回调更新父组件状态。具体步骤如下:


1. 父组件(Cart)修改

  • 定义回调函数onPriceChange,用于接收子组件传来的商品索引和对应价格,更新total数组
  • 给TableRow传递onPriceChange回调和index
  • 初始化total数组,长度与购物车商品数量一致,初始值为对应商品的初始总价(数量1时的价格)

修改后的父组件代码:

const Cart = () => {
  const { products } = useSelector((state) => state.allProducts);
  const cart = getStoredCart();
  const cartItems = products?.filter(({_id}) => cart.some(x => x.id === _id));
  
  // 初始化total数组,每个元素对应商品初始总价(数量1)
  const [total, setTotal] = useState(
    cartItems?.map(item => Number(item.price.toFixed(2))) || []
  );

  // 接收子组件传来的价格,更新对应索引的数组元素
  const onPriceChange = (index, newPrice) => {
    setTotal(prevTotal => {
      const updatedTotal = [...prevTotal];
      updatedTotal[index] = newPrice;
      return updatedTotal;
    });
  };

  return (
    <div className="mt-4">
      {cartItems?.length > 0 && (
        <>
          <div class="overflow-x-auto">
            <table class="table w-full">
              <thead className="">
                <tr className="text-center">
                  <th className="text-left">Product Details</th>
                  <th className="">Quantity</th>
                  <th className="">Price</th>
                </tr>
              </thead>
              <tbody>
                {cartItems?.map((item, index) => (
                  <TableRow 
                    key={item._id} 
                    item={item} 
                    index={index} 
                    onPriceChange={onPriceChange} // 传递回调
                  />
                ))}
              </tbody>
            </table>
          </div>
          {/* 可展示汇总金额 */}
          <div className="mt-4 text-right">
            <p className="font-bold">总金额: {total.reduce((sum, price) => sum + price, 0).toFixed(2)}</p>
          </div>
        </>
      )}
    </div>
  );
};

2. 子组件(TableRow)修改

  • 接收onPriceChange和index props
  • 使用useEffect监听quantity变化,每次变化后计算新价格并调用回调通知父组件
  • 给数量输入框添加最小值限制,避免出现小于1的数量

修改后的子组件代码:

import { useEffect, useState } from 'react';
import { HiMinus, HiPlus } from 'react-icons/hi';

const TableRow = ({ item, index, onPriceChange }) => {
  const [quantity, setQuantity] = useState(1);
  // 计算当前商品总价
  const price = Number((quantity * Number(item.price)).toFixed(2));

  // 当quantity或商品价格变化时,通知父组件更新对应价格
  useEffect(() => {
    onPriceChange(index, price);
  }, [quantity, item.price, index, onPriceChange]);

  const handlePrice = (type) => {
    if (type === 0) {
      setQuantity(prevQ => prevQ + 1);
    } else if (type === 1) {
      if (quantity > 1) {
        setQuantity(prevQ => prevQ - 1);
      }
    }
  };

  return (
    <tr>
      <td className="">
        <div className="flex space-x-2 items-center justify-center">
          <button onClick={() => handlePrice(1)} className="text-xl font-bold">
            <HiMinus />
          </button>
          <div className="w-16 h-10 border-2 rounded">
            <input
              className="w-full h-full text-center outline-none font-medium"
              type="number"
              value={quantity}
              onChange={(e) => setQuantity(Math.max(1, Number(e.target.value)))} // 限制数量不小于1
              min="1"
            />
          </div>
          <button onClick={() => handlePrice(0)} className="text-xl font-bold">
            <HiPlus />
          </button>
        </div>
      </td>
      <td className="w-40 text-center">{price}</td>
    </tr>
  );
};

关键说明

  • 回调传递:父组件通过onPriceChange回调接收子组件的价格更新,保证React状态单向流动的原则
  • useEffect监听:监听quantity和item.price的变化,确保价格变动时及时同步到父组件
  • 数组更新:父组件更新total数组时,使用展开运算符创建新数组,避免直接修改原状态(符合React状态不可变性要求)
  • 输入限制:通过min="1"和Math.max(1, ...)确保商品数量不会小于1,避免出现不合理的价格计算

内容的提问来源于stack exchange,提问作者Robiul Hasan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 18:54:19