Skip to content

Instantly share code, notes, and snippets.

@daviseford
Last active November 22, 2020 21:18
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save daviseford/4a0ed622dc47090fe22c1870217d88d6 to your computer and use it in GitHub Desktop.
Save daviseford/4a0ed622dc47090fe22c1870217d88d6 to your computer and use it in GitHub Desktop.
React Hooks - Async Stripe Provider
import React, { useState, useEffect, useRef } from 'react'
import { StripeProvider } from 'react-stripe-elements'
type TProvider = React.FC<{ apiKey: string }>
const AsyncStripeProvider: TProvider = props => {
const { apiKey, children } = props
const [stripe, setStripe] = useState<stripe.Stripe | null>(null)
const isMounted = useRef(false)
const unmountFn = () => {
isMounted.current = false
}
useEffect(() => {
isMounted.current = true
// If we already have stripe loaded, we don't need to do anything
if (stripe) return unmountFn
// Check if Stripe already exists in the window (probably from a previous mount)
if (window.Stripe) {
setStripe(window.Stripe(apiKey))
return unmountFn
}
// Otherwise, we need to create the script element
const stripeJs = document.createElement('script')
stripeJs.src = 'https://js.stripe.com/v3/'
stripeJs.async = true
// Tell our component what to do once the script has loaded
stripeJs.onload = () => {
// Only update Stripe if this component is still mounted
if (isMounted) setStripe(window.Stripe(apiKey))
}
// Add the script to the document
document.body && document.body.appendChild(stripeJs)
return unmountFn
}, [stripe, apiKey])
return (
<StripeProvider stripe={stripe}>
<>{children}</>
</StripeProvider>
)
}
export default AsyncStripeProvider
// Use the above component like so:
const StripeContainer = () => {
return (
<AsyncStripeProvider apiKey={"abc_123"}>
<Elements>
<YourPaymentComponent />
</Elements>
</AsyncStripeProvider>
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment