use Optimistic Cart
The takes an existing cart object, processes all pending cart actions, and locally mutates the cart with optimistic state. An optimistic cart makes cart actions immediately render in the browser while actions sync to the server. This increases the perceived performance of the application.
Anchor to useOptimisticCart-parametersParameters
- Anchor to cartcartcartDefaultCartDefaultCart
The cart object from
context.cart.get()returned by a server loader.
A new cart object augmented with optimistic state for
linesand. Each cart line item that is optimistically added includes anproperty. Also if the cart has any optimistic state, a root propertywill be set totrue.
OptimisticCart<DefaultCart = {
lines?: {
nodes: Array<{id: string; quantity: number; merchandise: {is: string}}>;
};
}>OptimisticCart<DefaultCart = {
lines?: {
nodes: Array<{id: string; quantity: number; merchandise: {is: string}}>;
};
}>
DefaultCart
Promise<CartReturn | null> | CartReturn | nullCartReturn
Cart & {
errors?: StorefrontApiErrors;
}Cart
CartStorefrontApiErrors
JsonGraphQLError[] | undefinedJsonGraphQLError
ReturnType<GraphQLError['toJSON']>OptimisticCart
T extends undefined | null
? // This is the null/undefined case, where the cart has yet to be created.
// But we still need to provide an optimistic cart object.
{
isOptimistic?: boolean;
lines: {
nodes: Array<OptimisticCartLine>;
};
totalQuantity?: number;
} & Omit<PartialDeep<CartReturn>, 'lines'>
: Omit<T, 'lines'> & {
isOptimistic?: boolean;
lines: {
nodes: Array<OptimisticCartLine<T>>;
};
totalQuantity?: number;
}OptimisticCartLine
T extends LikeACart
? T['lines']['nodes'][number] & {isOptimistic?: boolean}
: T & {isOptimistic?: boolean}LikeACart
- lines
{ nodes: unknown[]; }
{
lines: {
nodes: Array<unknown>;
};
}Examples
import {Link} from 'react-router';
import {CartForm, useOptimisticCart} from '@shopify/hydrogen';
// Root loader returns the cart data
export async function loader({context}) {
return {
cart: context.cart.get(),
};
}
// The cart component renders each line item in the cart.
export function Cart({cart}) {
// `useOptimisticCart` adds optimistic line items to the cart.
// These line items are displayed in the cart until the server responds.
const optimisticCart = useOptimisticCart(cart);
if (!optimisticCart?.lines?.nodes?.length) return <p>Nothing in cart</p>;
return optimisticCart.lines.nodes.map((line) => (
<div key={line.id}>
<Link to={`/products${line.merchandise.product.handle}`}>
{line.merchandise.product.title}
</Link>
<CartForm
route="/cart"
action={CartForm.ACTIONS.LinesRemove}
inputs={{lineIds: [line.id]}}
>
{/* Each line item has an `isOptimistic` property. Optimistic line items
should have actions disabled */}
<button type="submit" disabled={!!line.isOptimistic}>
Remove
</button>
</CartForm>
</div>
));
}
Examples
Example code
Description
I am the default example
JavaScript
import {Link} from 'react-router'; import {CartForm, useOptimisticCart} from '@shopify/hydrogen'; // Root loader returns the cart data export async function loader({context}) { return { cart: context.cart.get(), }; } // The cart component renders each line item in the cart. export function Cart({cart}) { // `useOptimisticCart` adds optimistic line items to the cart. // These line items are displayed in the cart until the server responds. const optimisticCart = useOptimisticCart(cart); if (!optimisticCart?.lines?.nodes?.length) return <p>Nothing in cart</p>; return optimisticCart.lines.nodes.map((line) => ( <div key={line.id}> <Link to={`/products${line.merchandise.product.handle}`}> {line.merchandise.product.title} </Link> <CartForm route="/cart" action={CartForm.ACTIONS.LinesRemove} inputs={{lineIds: [line.id]}} > {/* Each line item has an `isOptimistic` property. Optimistic line items should have actions disabled */} <button type="submit" disabled={!!line.isOptimistic}> Remove </button> </CartForm> </div> )); }TypeScript
import {type LoaderFunctionArgs} from 'react-router'; import {Link} from 'react-router'; import {CartForm, useOptimisticCart} from '@shopify/hydrogen'; import type {Cart} from '@shopify/hydrogen/storefront-api-types'; // Root loader returns the cart data export async function loader({context}: LoaderFunctionArgs) { return { cart: context.cart.get(), }; } // The cart component renders each line item in the cart. export function Cart({cart: originalCart}: {cart: Cart}) { // `useOptimisticCart` adds optimistic line items to the cart. // These line items are displayed in the cart until the server responds. const cart = useOptimisticCart(originalCart); if (!cart?.lines?.nodes?.length) return <p>Nothing in cart</p>; return cart.lines.nodes.map((line) => ( <div key={line.id}> <Link to={`/products${line.merchandise.product.handle}`}> {line.merchandise.product.title} </Link> <CartForm route="/cart" action={CartForm.ACTIONS.LinesRemove} inputs={{lineIds: [line.id]}} > {/* Each line item has an `isOptimistic` property. Optimistic line items should have actions disabled */} <button type="submit" disabled={!!line.isOptimistic}> Remove </button> </CartForm> </div> )); }
Was this page helpful?