'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 |