Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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;
like image 559
Eipu Too Avatar asked Nov 05 '20 08:11

Eipu Too


People also ask

How do I remount a component when a prop changes?

To remount a component when a prop changes, use the React key attribute as described in this post on the React blog: When a key changes, React will create a new component instance rather than update the current one. The example below shows how the key attribute can be used.

How to highlight text when prop is changed by parent component?

The guide will start with a very simple label component that will have a prop called text and display it inside a span, then extend this component to highlight the text when the prop is changed by the parent component.

How do I highlight the background color of a text prop?

This can be achieved by passing an empty array as the second parameter and returning a function that will then be called when the component is being umounted. The code for this looks like: Add these two calls to useEffect into the Label function and the background color will now highlight for a second whenever the text prop changes.


2 Answers

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))
like image 184
Nikita Chayka Avatar answered Nov 15 '22 04:11

Nikita Chayka


I had the same error.

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

Noman's comment is the ideal solution for most of cases, but that doesn't work if the Stripe account depends on React state. This usually happens if you are building apps with Stripe Connect.

In that case, 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 re-render!

like image 28
Kazuya Gosho Avatar answered Nov 15 '22 05:11

Kazuya Gosho