在这种情况下我尝试使用具有不同参数的 RTK 查询:
我有多个商品的购物车,每个商品都有计数器来控制购买商品的数量,以便我可以添加或删除(增加或减少数量)。
问题:
虽然所有计数器都具有相同的 RTK 查询定义,但它们共享突变触发器和 isLoading 属性,因此当单击一个按钮时,isLoading 属性会切换为 true 并在所有其他计数器按钮上显示微调器
购物车组件代码:
const Cart = () => {
const {
isLoading,
isSuccess,
data: cart,
} = useGetCartQuery({ userId: userData.id });
const [addItem, { isLoading: isAddUpdating }] = useAddCartMutation();
const [removeItem, { isLoading: isRemoveUpdating }] = useRemoveCartMutation();
const handleAddBtn = (item: cartItemType) => {
if (item.product.availability > item.quantity) {
addItem({
userId: userData.id as string,
productId: item.product.id as string,
quantity: 1,
});
} else {
throw new Error("can't add more than items in stack");
}
};
const handleRemoveBtn = (item: cartItemType, count) => {
console.log(item, count);
if (item.quantity >= count) {
removeItem({
userId: userData.id as string,
productId: item.product.id as string,
count: count,
});
}
};
return (
<div>
<QCounter
availability={item.product.availability}
count={item.quantity}
handleAddBtn={() => handleAddBtn(item)}
handleRemoveBtn={() => handleRemoveBtn(item, 1)}
AddBtnLoading={isAddUpdating}
RemoveBtnLoading={isRemoveUpdating}
height="36px"
width="36px"
/>
</div>
);
};
Q柜台代码:
const QCounter = ({
availability,
count,
handleAddBtn,
handleRemoveBtn,
AddBtnLoading,
RemoveBtnLoading,
height,
width,
}) => {
return (
<div>
<button
onClick={handleRemoveBtn}
disabled={count == 1 || RemoveBtnLoading}
>
{!RemoveBtnLoading ? (
"-"
) : (
<FaSpinner className="animate-spin text-secondary" />
)}
</button>
<div>
<h3>{count}</h3>
</div>
<button
onClick={handleAddBtn}
disabled={count == availability || AddBtnLoading}
>
{!AddBtnLoading ? (
"+"
) : (
<FaSpinner className="animate-spin text-secondary" />
)}
</button>
</div>
);
};
我尝试过的解决方案:
1-使用地图功能为每个项目定义RTK查询功能
我尝试用这样的地图函数来定义它们
{cart.items.map((item: cartItemType) => {
const [addItem, { isLoading: isAddUpdating }] = useAddCartMutation();
const [removeItem, { isLoading: isRemoveUpdating }] = useRemoveCartMutation();
然后将 addItem 和 isLoading 传递给每个 Qcounter 但我收到 TS 错误:
必须在 React 函数组件或自定义 React Hook 函数中调用 React Hook。
如果我正在阅读并理解帖子和代码,您可能会将从
cart
返回的 useGetCartQuery
数据映射到第一个片段中的 QCounter
,并希望每个 QCounter
都有自己的添加/删除“状态”和指示器。
您不能在循环或嵌套回调中调用突变 React hooks,因为这会破坏 Hooks 规则。我建议将突变挂钩和添加/删除逻辑移至
QCounter
组件中,以便每个购物车项目都有自己的状态和逻辑。
示例:
购物车:
const Cart = () => {
...
const {
isLoading,
isSuccess,
data: cart,
} = useGetCartQuery({ userId: userData.id });
return (
<div>
{cart.items.map((item: cartItemType) => (
<QCounter
key={item.product.id}
item={item}
userId={userData.id}
height="36px"
width="36px"
/>
))}
</div>
);
};
Q计数器:
interface QCounterProps {
item: cartItemType;
userId: string;
height: string;
width: string;
}
const QCounter = ({
height,
item,
userId,
width,
}: QCounterProps) => {
const [
addItem,
{ isLoading: isAddUpdating }
] = useAddCartMutation();
const [
removeItem,
{ isLoading: isRemoveUpdating }
] = useRemoveCartMutation();
const handleAddBtn = () => {
if (item.product.availability > item.quantity) {
addItem({
userId,
productId: item.product.id as string,
quantity: 1,
});
} else {
throw new Error("can't add more than items in stack");
}
};
const handleRemoveBtn = () => {
if (item.quantity > 0) {
removeItem({
userId,
productId: item.product.id as string,
count: item.quantity,
});
}
};
return (
<div>
<button
onClick={handleRemoveBtn}
disabled={item.quantity === 1 || isRemoveUpdating}
>
{isRemoveUpdating
? <FaSpinner className="animate-spin text-secondary" />
: "-"
}
</button>
<div>
<h3>{item.quantity}</h3>
</div>
<button
onClick={handleAddBtn}
disabled={item.quantity === item.product.availability || isAddUpdating}
>
{isAddUpdating
? <FaSpinner className="animate-spin text-secondary" />
: "+"
}
</button>
</div>
);
};