Fix: Move useOptimistic to provider level for consistent cart state

- Move useOptimistic from useCart hook to CartProvider
- Create single shared optimistic cart instance
- Eliminate lag between cart operations and UI updates
- Ensure all components see consistent cart state
This commit is contained in:
Franco May 2025-07-01 10:50:53 +02:00
parent fa1306916c
commit cf3c0be0f3

View File

@ -28,6 +28,8 @@ type CartAction =
type CartContextType = { type CartContextType = {
cartPromise: Promise<Cart | undefined>; cartPromise: Promise<Cart | undefined>;
optimisticCart: Cart | undefined;
updateOptimisticCart: (action: CartAction) => void;
}; };
const CartContext = createContext<CartContextType | undefined>(undefined); const CartContext = createContext<CartContextType | undefined>(undefined);
@ -197,8 +199,14 @@ export function CartProvider({
children: React.ReactNode; children: React.ReactNode;
cartPromise: Promise<Cart | undefined>; cartPromise: Promise<Cart | undefined>;
}) { }) {
const initialCart = use(cartPromise);
const [optimisticCart, updateOptimisticCart] = useOptimistic(
initialCart,
cartReducer
);
return ( return (
<CartContext.Provider value={{ cartPromise }}> <CartContext.Provider value={{ cartPromise, optimisticCart, updateOptimisticCart }}>
{children} {children}
</CartContext.Provider> </CartContext.Provider>
); );
@ -210,29 +218,23 @@ export function useCart() {
throw new Error('useCart must be used within a CartProvider'); throw new Error('useCart must be used within a CartProvider');
} }
const initialCart = use(context.cartPromise);
const [optimisticCart, updateOptimisticCart] = useOptimistic(
initialCart,
cartReducer
);
const updateCartItem = (merchandiseId: string, updateType: UpdateType) => { const updateCartItem = (merchandiseId: string, updateType: UpdateType) => {
updateOptimisticCart({ context.updateOptimisticCart({
type: 'UPDATE_ITEM', type: 'UPDATE_ITEM',
payload: { merchandiseId, updateType } payload: { merchandiseId, updateType }
}); });
}; };
const addCartItem = (variant: ProductVariant, product: Product) => { const addCartItem = (variant: ProductVariant, product: Product) => {
updateOptimisticCart({ type: 'ADD_ITEM', payload: { variant, product } }); context.updateOptimisticCart({ type: 'ADD_ITEM', payload: { variant, product } });
}; };
return useMemo( return useMemo(
() => ({ () => ({
cart: optimisticCart, cart: context.optimisticCart,
updateCartItem, updateCartItem,
addCartItem addCartItem
}), }),
[optimisticCart] [context.optimisticCart, context.updateOptimisticCart]
); );
} }