'Unsupported prop change on Elements: You cannot change the `stripe` prop after setting it

Stripe Payment is completely work but i got the warning message on the console, "Unsupported prop change on Elements: You cannot change the stripe prop after setting it." Here is my code. I have no idea why the warning message is showing, what do i miss?

const Parent =() => {
        const stripePromise = loadStripe(PUBLISHABLE_KEY);
        <Elements stripe ={stripePromise}>
          <Child_component/>
        </Elements> 
}
export default Parent;

import {CardNumberElement, CardExpiryElement, CardCvcElement} from '@stripe/react-stripe-js';
const Child_component =() => {
        const handleChange = (event) => {
               //get the brand type
        };
        const handleFormSubmit = async ev =>{
           const cardElement = elements.getElement(CardNumberElement);
           const paymentMethodReq = await stripe.createPaymentMethod({
                    type: 'card',
                    card: cardElement
           });
           /// and send paymentMethodReq to the backend.
        }
   render(
       <Form className="" onSubmit={handleFormSubmit}>
        <div className="split-form full-width inline-block pt-4">
            <div className="row">
                <div className="col-12">
                    <label className="card-element">
                        Card number
                        <CardNumberElement
                        className="cardNumberElement"
                        onChange={handleChange}
                        />
                    </label>
                </div>
                <div className="col-8">
                    <label className="card-element">
                        Expiration date
                        <CardExpiryElement
                        onChange={handleChange}
                        />
                    </label>
                </div>
                <div className="col-4">
                    <label className="card-element">
                        CVC
                        <CardCvcElement 
                        onChange={handleChange}
                        />
                    </label>
                </div>
            </div>
        </div>
       </Form>
     )
 }
 export default Child_component;


Solution 1:[1]

Your problem is that in your Parent component you just do

const stripePromise = loadStripe(PUBLISHABLE_KEY);

What it means is actually on each render you will get new promise object (new stripePromise) every time, that's exactly what <Element> component is complaining about. What you should do instead, to not get new instance all the time on render, you should put loadStripe function in state, but because it is a function, you actually need to wrap it up in another function because of this - https://reactjs.org/docs/hooks-reference.html#lazy-initial-state.

So how should look like:

const [stripePromise, setStripePromise] = useState(() => loadStripe(PUBLISHABLE_KEY))

Solution 2:[2]

I had the same error.

what if we move the stripePromise variable outside the functional component? – Noman Gul Feb 5 at 17:35

That is the ideal solution if the component doesn't depend on state.

If you want to pass an option to loadStripe, you should use useMemo to memoize the promise.

const Parent = ({ stripeAccount }) => {
  const stripePromise = useMemo(
    () => loadStripe(PUBLISHABLE_KEY, { stripeAccount }),
    [stripeAccount],
  )

  return (
    <Elements stripe={stripePromise}>
      <Child_component/>
    </Elements> 
  )
}

Otherwise, the component loads stripe every render!

Solution 3:[3]

Example using Noman's comment and just moving the promise outside of the functional component

what if we move the stripePromise variable outside the functional component? – Noman Gul Feb 5 at 17:35

This is working perfectly for me.

const stripePubKey = 'your-stripe-publishable-key';
const stripePromise = loadStripe(stripePubKey);

const Parent: React.FC = () => {
  return (
    <Elements stripe={stripePromise}>
      <Child />
    </Elements> 
  )
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Grzegorz
Solution 2 Kazuya Gosho
Solution 3