@nacelle/react-hooks
v8.0.0
Published
Custom convenience hooks for use when building apps with Nacelle
Downloads
597
Readme
@nacelle/react-hooks
React Hooks for Nacelle-fueled storefronts
Install
npm i @nacelle/react-hooks
Using the Hooks
useCheckout
Use a checkout provider to create and manage checkouts.
Setting Up the Provider
Because checkout data and checkout actions should exist across the app, the <CheckoutProvider />
needs to surround the root component of the application. The provider requires a checkoutClient
prop, which is given an instance of a checkout client such as @nacelle/shopify-checkout
. For example:
import { CheckoutProvider } from '@nacelle/react-hooks';
import createShopifyCheckoutClient from '@nacelle/shopify-checkout';
const shopifyCheckoutClient = createShopifyCheckoutClient({
// for more info, see https://www.npmjs.com/package/@nacelle/shopify-checkout
storefrontCheckoutToken: process.env.SHOPIFY_STOREFRONT_CHECKOUT_TOKEN,
myshopifyDomain: process.env.MYSHOPIFY_DOMAIN,
storefrontApiVersion: process.env.STOREFRONT_API_VERSION
});
const App = () => {
<CheckoutProvider checkoutClient={shopifyCheckoutClient}>
<main>...</main>
</CheckoutProvider>;
};
You're welcome to create your own checkout client. It just needs to expose two methods:
function get(
params: any
): Promise<{
id: string;
url: string;
completed: boolean;
} | void> {
try {
// fetch an existing checkout
} catch (err) {
throw new Error(err);
}
}
function process(
params: any
): Promise<{
id: string;
url: string;
completed: boolean;
} | void> {
try {
// create a new checkout or update an existing checkout
} catch (err) {
throw new Error(err);
}
}
The useCheckout
Hook
Importing
import { useCheckout } from '@nacelle/react-hooks';
Accepts
(None)
Returns
An array containing:
checkoutData
: an object containing the following properties:
completed
(boolean) - signals whether the checkout process has successfully completedid
(string) - the checkout IDurl
(string) - the URL of the checkout pagegetCheckoutError
(string) - error returned from the checkout client when fetching an existing checkoutprocessCheckoutError
(string) - error returned from the checkout client when processing a checkout
checkoutActions
: an object containing the following properties:
processCheckout(params)
: (function) initiates checkout processing- Accepts parameters required by the checkout client's
process
method - Either rejects with an error message, or returns a promise which resolves to an object containing the
completed
,id
, andurl
- Accepts parameters required by the checkout client's
getCheckout(params)
(function) updates thecheckoutData
(note:useCheckout
runs this function automatically - it is provided only to satisfy special use cases)- Accepts parameters required by the checkout client's
get
method - Either rejects with an error message, or returns a promise which resolves to an object containing the
completed
,id
, andurl
- Accepts parameters required by the checkout client's
clearCheckoutData
: (function) when called, resets thecheckoutData
and clearscheckoutData
values stored in browser storage- Accepts: N/A
- Returns: N/A
isCheckingOut
: a boolean that indicates whether or not theprocessCheckout
function is currently running
Example Usage
// Using the useCheckout hook
//
// This example assumes that you're creating a Shopify
// checkout with `@nacelle/shopify-checkout. For more info,
// see https://www.npmjs.com/package/@nacelle/shopify-checkout.
//
// If using a different checkout client, adjust the `processCheckout`
// params accordingly.
import { useCheckout } from '@nacelle/react-hooks';
const Cart = () => {
const [checkoutData, checkoutActions, isCheckingOut] = useCheckout();
const cartItems = [
{ variantId: 123456789, quantity: 1 },
{ variantId: 987654321, quantity: 4 }
];
useEffect(() => {
if (checkoutData.completed) {
checkoutActions.clearCheckoutData();
// any other post-checkout actions, such as clearing the cart
}
}, [checkoutData.completed, clearCheckoutData]);
const processCheckout = async () => {
await checkoutActions.processCheckout({ cartItems }).then(() => {
window.location = checkoutData.url;
});
};
return (
<>
<h2>Cart</h2>
<button type="button" disabled={isCheckingOut} onClick={processCheckout}>
{isLoading ? <>Loading...</> : <>Checkout</>}
</button>
</>
);
};
useCart
A hook which uses items in a cart to generate a checkout via Nacelle's Hail Frequency API.
Setting Up the Provider
Because the cart should exist across the app, it needs to be setup to surround the root component of the application.
import { CartProvider } from '@nacelle/react-hooks';
const App = () => {
<CartProvider>
<main>...</main>
</CartProvider>;
};
Cart Persistence
By default, the <CartProvider />
uses Local Storage to persist the cart between refreshes. If you would prefer to use Session Storage instead of Local Storage, pass storage={'session'}
as a prop. If you would prefer to use Index DB Storage instead, pass storage={'idb'}
as a prop. To disable cart storage entirely, pass storage={null}
as a prop.
When using Local Storage or Session Storage to perist the cart, the default storage key of 'cart'
can be overriden by supplying a cacheKey="my-custom-cart=key"
prop.
The useCart
Hook
Importing
import { useCart } from '@nacelle/react-hooks';
Accepts
(None)
Returns
An array containing:
cartState
: an object containing the current state of the cart. The properties of this object are:
cart
: an array of line items in the cartshow
: a boolean to determine if the cart should be shown
cartActions
: an object containing methods for interacting with the cart:
initCart(items)
- initialize/override the cart with an array of cart itemsaddToCart(item)
- add an item to the cart; if the item is already in the cart this function will increase the quantity of that itemupdateItem(item)
- modify properties of an item in the cartremoveFromCart(item)
- remove an item from the cartincrementItem(item)
- increment the quantity of an item in the cartdecrementItem(item)
- decrement the quantity of an item in the carttoggleCart()
- toggles the cart's show status- Optionally, accepts one of the following string arguments:
'open'
- ifcartState.show
wasfalse
, it will change totrue
; ifcartState.show
wastrue
, it will remaintrue
'closed'
- ifcartState.show
wasfalse
, it will remainfalse
; ifcartState.show
wastrue
, it will change tofalse
- Optionally, accepts one of the following string arguments:
clearCart()
- removes all items from the cart
isInCart
- a helper function that determines if a line item is in the cart, viaisInCart(cart, item)
. If a customisInCart
function is given to the<CartProvider />
via theisInCart
prop, the custom function will be returned instead of the defaultisInCart
function.
Example Usage
// Using the useCart hook
import { useCart } from '@nacelle/react-hooks';
const Cart = () => {
const [{ cart }, { clearCart }] = useCart();
return (
<>
<h2>Cart</h2>
<button onClick={clearCart}>Clear</button>
<ul>
{cart.map((item) => (
<li key={item.id}>
<h3>{item.title}</h3>
<span>{item.quantity}</span>
<span>{item.price}</span>
</li>
))}
</ul>
</>
);
};
License
ISC © getnacelle