In React, validate CardElement is not blank client-side with useRef()

Viewed 17

We are using to accept payment info as part of a signup form, and for the form, would like to know whether or not the is complete. The solution here - Stripe elements: how can I validate a card element is not blank client-side? - uses document.querySelector() rather than the useRef() hook.

CardElement with surrounding container for styles

const OurCardElement = React.forwardRef((props, ref) => {
    return (
        <OurElementContainer>
            <CardElement
                ref={ref}
                isDisabled={true}
                options={cardElementOpts}
            />
        </CardElementContainer>
    );
});

Our signup page looks something like this:

const SignupPage = () => {
    // hooks
    const stripe = useStripe();
    const elements = useElements();
    const cardElementRef = useRef();

    // want the card state here (this isn't working)
    let isCardComplete = ref.current.className.includes('StripeElement--complete')            

    // signup handler
    const handleSignup = async (e) => {
        const cardElement = elements.getElement('card');
        e.preventDefault();

        try {
            // subscribe
            cardElement.update({ disabled: true });
            const paymentMethodReq = await stripe.createPaymentMethod({
                type: 'card',
                card: cardElement
            });

            // Handle Creating Payment Subscription
            let paymentObject = {
                id,
                paymentMethod: paymentMethodReq.paymentMethod.id
            };
            const stripeResponse = await Axios.post(`${apiBaseUrl}/stripe/new_payment_subscriptions`, paymentObject);

        } catch (err) {
            console.log(err);
        }
    };

    // Return
    return (
        ... rest of signup form (name, email, password, etc.)
        <OurCardElement ref={cardElementRef} /> // submit payment info
        <button 
            onClick={() => handleSignup}
            isDisabled={!isCardComplete}
        />
    );
});

We have a form (not shown) for name, email, password, a for submitting credit card info, a submit button, and a handler function for handling submit, which creates the user in our database (not shown) and sets up the stripe payment as well.

It would appear that we cannot attach the ref to the <CardElement> container. We receive the error Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?

We are trying this approach because, as mentioned in Stripe elements: how can I validate a card element is not blank client-side? , we can use the className of the card element to identify if the card element is empty / complete / etc. How can we otherwise use useRef() to get the class from the card element for this? Or is there another way, not using either useRef() or document.querySelector() to grab the className, that we can use to identify if the card element is accurately filled in?

0 Answers
Related