How do I share a piece of data between a series of CheckoutUIExtensions?

I am building a series of shopify checkout UI extensions, because they have pulled the rug out from under us Shopify Plus customers and removed the ability to modify our checkout.liquid files. The system I am building is a rewards/points keeping system that tracks and rewards people for purchasing certain items. [[extensions.targeting]] module = "./src/Banner.tsx" target = "purchase.checkout.block.render" [[extensions.targeting]] module = "./src/LineItems.tsx" target = "purchase.checkout.cart-line-item.render-after" [[extensions.targeting]] module = "./src/Calculator.tsx" target = "purchase.checkout.reductions.render-after" All I want to do is share a single integer between all 3 components. This integer is just a multiplier for a points keeping/rewards system. I am new to react and have recently learned of useContext. But I'm not sure how to share it between 3 .tsx files. Really all my components kind of look like this below and I just want that one variable to be shared between all 3 of these components so that I can update it in one place. We frequently change these multipliers based on promotions so having it in a single spot is ideal. import { useEffect, useState, useRef } from 'react'; import { Heading, useApi, InlineLayout, Text, View, useApplyDiscountCodeChange, useDiscountCodes, useAppMetafields, reactExtension, } from '@shopify/ui-extensions-react/checkout'; export default reactExtension( 'purchase.checkout.reductions.render-after', () => <Extension />, ); function Extension() { const { extension, lines } = useApi(); const productMetaDatas = useAppMetafields({ type: "product", namespace: "custom", key: "entry_override_arbitrary_value" }); let multiplier = 40; let [messageHeader, setMessageHeader] = useState('Total Entries'); let [message, setMessage] = useState('You will receive 40 entries for every $1 spent!'); const discountCodes = useDiscountCodes(); const ApplyDiscountCodeChange = useApplyDiscountCodeChange(); useEffect(() => { let tempEntries = 0; lines.current.forEach(function (cartLineTarget) { // Get the product ID from the cart line item const productId = cartLineTarget?.merchandise?.product?.id; if (!productId) { return; } const productMetaData = productMetaDatas.find(({ target }) => { return `gid://shopify/Product/${target.id}` === productId; }); if (productMetaData?.metafield.value) { tempEntries += parseInt(productMetaData.metafield.value) * cartLineTarget.quantity; } else { tempEntries += Math.floor(cartLineTarget.cost.totalAmount.amount) * cartLineTarget.quantity * multiplier; } }); const bonusDiscountCodes = [ { 'FREESHIPPING2024': 50 }, { 'CLOWNSHOES': 20 }, ]; if (discountCodes.length > 0) { const isActiveDiscountCodeInBonus = bonusDiscountCodes.some(discountCodeObj => Object.keys(discountCodeObj).includes(discountCodes[0].code) ); if (isActiveDiscountCodeInBonus) { tempEntries += 50; } } setMessage(tempEntries); }, [message, messageHeader, lines, productMetaDatas, discountCodes]); return ( <InlineLayout columns={['fill', '20%']}> <View> <Heading level="2">{messageHeader}</Heading> </View> <View inlineAlignment="end"> <Text appearance="info">{message}</Text> </View> </InlineLayout> ); } Right now I've just duplicated the declared "multiplier" variable between all 3 components. But that's not an ideal situation. I know there is a simple solution but I cant for the life of me figure it out.

Comment (0)

You’ll be in good company