react-stripe-elements not detecting Stripe.js

Viewed 2624

I have a weird problem with react-stripe-elements. The module is crashing with an uncaught error which reads as follows:

Uncaught Error: Please load Stripe.js (https://js.stripe.com/v3/) on this page to use react-stripe-elements.
    at new Provider (Provider.js:38)
    at ReactCompositeComponent.js:294
    at measureLifeCyclePerf (ReactCompositeComponent.js:75)
    at ReactCompositeComponentWrapper._constructComponentWithoutOwner (ReactCompositeComponent.js:293)
    at ReactCompositeComponentWrapper._constructComponent (ReactCompositeComponent.js:279)
    at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:187)
    at Object.mountComponent (ReactReconciler.js:45)
    at ReactDOMComponent.mountChildren (ReactMultiChild.js:236)
    at ReactDOMComponent._createInitialChildren (ReactDOMComponent.js:703)
    at ReactDOMComponent.mountComponent (ReactDOMComponent.js:522)
    at Object.mountComponent (ReactReconciler.js:45)
    at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:370)
    at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:257)
    at Object.mountComponent (ReactReconciler.js:45)
    at ReactDOMComponent.mountChildren (ReactMultiChild.js:236)
    at ReactDOMComponent._createInitialChildren (ReactDOMComponent.js:703)
    at ReactDOMComponent.mountComponent (ReactDOMComponent.js:522)
    at Object.mountComponent (ReactReconciler.js:45)
    at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:370)
    at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:257)
    at Object.mountComponent (ReactReconciler.js:45)
    at Object.updateChildren (ReactChildReconciler.js:121)
    at ReactDOMComponent._reconcilerUpdateChildren (ReactMultiChild.js:206)
    at ReactDOMComponent._updateChildren (ReactMultiChild.js:310)
    at ReactDOMComponent.updateChildren (ReactMultiChild.js:297)
    at ReactDOMComponent._updateDOMChildren (ReactDOMComponent.js:942)
    at ReactDOMComponent.updateComponent (ReactDOMComponent.js:760)
    at ReactDOMComponent.receiveComponent (ReactDOMComponent.js:722)
    at Object.receiveComponent (ReactReconciler.js:124)
    at ReactCompositeComponentWrapper._updateRenderedComponent (ReactCompositeComponent.js:753)
    at ReactCompositeComponentWrapper._performComponentUpdate (ReactCompositeComponent.js:723)
    at ReactCompositeComponentWrapper.updateComponent (ReactCompositeComponent.js:644)
    at ReactCompositeComponentWrapper.receiveComponent (ReactCompositeComponent.js:546)
    at Object.receiveComponent (ReactReconciler.js:124)
    at Object.updateChildren (ReactChildReconciler.js:109)
    at ReactDOMComponent._reconcilerUpdateChildren (ReactMultiChild.js:206)
    at ReactDOMComponent._updateChildren (ReactMultiChild.js:310)
    at ReactDOMComponent.updateChildren (ReactMultiChild.js:297)
    at ReactDOMComponent._updateDOMChildren (ReactDOMComponent.js:942)
    at ReactDOMComponent.updateComponent (ReactDOMComponent.js:760)
    at ReactDOMComponent.receiveComponent (ReactDOMComponent.js:722)
    at Object.receiveComponent (ReactReconciler.js:124)
    at Object.updateChildren (ReactChildReconciler.js:109)
    at ReactDOMComponent._reconcilerUpdateChildren (ReactMultiChild.js:206)
    at ReactDOMComponent._updateChildren (ReactMultiChild.js:310)
    at ReactDOMComponent.updateChildren (ReactMultiChild.js:297)
    at ReactDOMComponent._updateDOMChildren (ReactDOMComponent.js:942)
    at ReactDOMComponent.updateComponent (ReactDOMComponent.js:760)
    at ReactDOMComponent.receiveComponent (ReactDOMComponent.js:722)
    at Object.receiveComponent (ReactReconciler.js:124)

The module seems to think that Stripe.js is not loaded. However, I have confirmed the following to be in the <head>:

<script src="https://js.stripe.com/v3/"></script>

This is consistent with the instructions provided by stripe here.

If I refresh the page, it loads fine without throwing an error!

The situation seems so simple that I'm not even sure what avenue to take to debug it. Stripe js should be present, and it is, but it isn't detected. Has anyone experienced this problem or have any idea how to approach it?

2 Answers

Create a function which returns Promise to load stripe.js and use React Hooks(useState, useEffect) to trigger actions to show React Stripe Elements when Stripe script loaded.

import React, { useState, useEffect } from 'react
import {
  StripeProvider,
  Elements,
  CardNumberElement
} from 'react-stripe-elements'

const loadScript = src =>
  new Promise((resolve, reject) => {
    const script = document.createElement('script')
    script.src = src
    script.addEventListener('load', () => {
      resolve({ successful: true })
    })
    script.addEventListener('error', event => {
      reject({ error: event })
    })
    document.head.appendChild(script)
  })

const MyComponent = () => {
 const [stripeLoaded, setStripeLoaded] = useState({})
  useEffect(() => {
    const fetchData = async () => {
      const result = await loadScript('https://js.stripe.com/v3/')
      setStripeLoaded(result)
    }
    fetchData()
  }, []) // eslint-disable-line react-hooks/exhaustive-deps 

  return  stripeLoaded.successful ? (
    <StripeProvider>
      <Elements>
        <CardNumberElement />
      </Elements>
    </StripeProvider>) : null
}
Related