skip to Main Content

i followed this example https://stripe.com/docs/payments/link/add-link-elements-integration

I see the form where you put in credit card info.
clicking around inside and outside the form, it constantly re-renders, page refreshes.
I dont think the form preventDefault is working.
This issue is occurs in chrome, chrome incognito, and safari.

any idea why page constantly refreshes?

// PayScreen.tsx
const stripePromise = loadStripe(config.stripePublishableKey)
export default function CreatePaymentScreen() {
  // this code is updated from the comments below. still same problem.

  const { data, isLoading } = useQuery({
    queryFn: async () => await createPaymentIntent(), 
    // stripe_client().PaymentIntent.create backend function
  })
  const clientSecret = data?.intent?.client_secret
  const email = data?.customer?.email

  if (isLoading || !stripe)
   return null
  return (
    <Elements stripe={stripePromise} options={{ clientSecret }}>
        <CheckoutForm email={email} />
    </Elements>
  )
}
// CheckoutForm.tsx literal verbatim from https://stripe.com/docs/stripe-js/react#elements-provider
import { useStripe, useElements, PaymentElement } from '@stripe/react-stripe-js'

const CheckoutForm = () => {
  const stripe = useStripe()
  const elements = useElements()

  const handleSubmit = async (event: any) => {
    // We don't want to let default form submission happen here,
    // which would refresh the page.
    event.preventDefault()

    if (!stripe || !elements) {
      // Stripe.js hasn't yet loaded.
      // Make sure to disable form submission until Stripe.js has loaded.
      return
    }

    const result = await stripe.confirmPayment({
      // `Elements` instance that was used to create the Payment Element
      elements,
      confirmParams: {
        return_url: "https://example.com/order/123/complete",
      },
    })

    if (result.error) {
      // Show error to your customer (for example, payment details incomplete)
      console.log(result.error.message)
    } else {
      // Your customer will be redirected to your `return_url`. For some payment
      // methods like iDEAL, your customer will be redirected to an intermediate
      // site first to authorize the payment, then redirected to the `return_url`.
    }
  }

  return (
    <div>
      <PaymentElement />
      <button onSubmit={handleSubmit} disabled={!stripe}>Submit</button>
    </div>
  )
}

export default CheckoutForm
// package.json
    "@stripe/react-stripe-js": "^2.4.0",
    "@stripe/stripe-js": "^2.4.0",

my problem is different from
Stripe payment form constantly re-renders using @stripe/react-stripe-js

2

Answers


  1. Chosen as BEST ANSWER

    its useQuery. changed to useEffect, and its fine


  2. You should just pass stripePromise to <Elements> directly. There’s no need to use useEffect and useState hooks to set an instance of Stripe. Refer to the integration doc for more details.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search