Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stripe reactjs - could not find elements context

I am working on a ReactJS project where I want to integrate stripe to allow users to update their payment information for a subscription.

I am following the guide at https://stripe.com/docs/stripe-js/react but I am hitting an issue.

Below is the code that I currently have

const stripe = useStripe();
    const elements = useElements();

    const errorDialogueCleared = () => {
        setAPIResult(null);
    }

    const stripePromise = loadStripe('my_test_key');

    const baseStripeElementOptions = {
        style: {
            base: {
                fontFamily: 'Oxanium',
                fontSize: '16px',
                    color: '#000000',
                    '::placeholder': {
                    color: '#000000',
                },
            },
            invalid: {
                color: '#9e2146',
            },
        }
    }

    const handleSubmit = async (event) => {
        // Block native form submission.
        event.preventDefault();

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

        // Get a reference to a mounted CardElement. Elements knows how
        // to find your CardElement because there can only ever be one of
        // each type of element.
        const cardElement = elements.getElement(CardElement);

        // Use your card Element with other Stripe.js APIs
        const {error, paymentMethod} = await stripe.createPaymentMethod({
            type: 'card',
            card: cardElement,
        });

        if (error) {
            console.log('[error]', error);
        } else {
            console.log('[PaymentMethod]', paymentMethod);
        }
    };

    return (

        <div className='container-fluid'>

            <div className="mainContentNoSidebar">

                <TopNavBar displayTimePeriodButton={false} title='Update Account Information' />

                <BreadcrumbNav menu_items={breadcrumbNav} />

                <div className='contentWrapper'>

                    <div className='container'>
                        <h1>Update Account Information</h1>
                        <form onSubmit={handleSubmit} style={{width: '50%', marginLeft: 'auto', marginRight: 'auto'}}>
                            <Elements stripe={stripePromise}>
                                <CardElement options={baseStripeElementOptions} />
                            </Elements>

                            <button className='btn btn-primary'>Submit Payment Details</button>
                        </form>
                    </div>



                </div>
            </div>

            <ErrorDialogue dialogClosed={errorDialogueCleared} api_result={currentError} />
        </div>
    )
}

However, although it feels like I've followed the documentation I am getting the following error as soon as the page loads:

Error: Could not find Elements context; You need to wrap the part of your app that calls useStripe() in an provider

My CardElement is wrapped in an Elements components so I'm not sure why I am seeing this error.

like image 443
Boardy Avatar asked Jan 22 '26 20:01

Boardy


2 Answers

You cannot call useElements unless you're already have the correct stripe context.

This means that your whole component you're showing here should be wrapped by Elements and not just the CardElement.

It should like this:

import {Elements} from '@stripe/react-stripe-js';
import {loadStripe} from '@stripe/stripe-js';

const stripePromise = loadStripe('STRIPE_PUBLISHABLE_API_KEY');

const Wrapper = (props) => (
  <Elements stripe={stripePromise}>
    <MyComponent {...props} />
  </Elements>
);

const MyComponent = (props) => {
  const stripe = useStripe();
  const elements = useElements();

  // rest of the component
};
like image 192
Axnyff Avatar answered Jan 24 '26 16:01

Axnyff


Just put your component into a Parent Component, which is wrapped in the Elements Tag:

import React from "react";
import {Elements} from '@stripe/react-stripe-js';
import {loadStripe} from '@stripe/stripe-js';
import ChildComponent from './ChildComponent'

const ParentComponent= () => (
  <Elements stripe={stripePromise}>
    <ChildComponent />
  </Elements>
);
like image 21
Ahmedakhtar11 Avatar answered Jan 24 '26 16:01

Ahmedakhtar11