Skip to content

Commit

Permalink
Initialize stripe.elements on component did mount
Browse files Browse the repository at this point in the history
  • Loading branch information
khmm12 committed Jun 8, 2020
1 parent 581499c commit bd35e6d
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 35 deletions.
38 changes: 18 additions & 20 deletions src/components/Elements.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,7 @@ describe('Elements', () => {
expect(mockStripe.elements).toHaveBeenCalledTimes(1);
});

// TODO(christopher): support Strict Mode first
// eslint-disable-next-line jest/no-disabled-tests
test.skip('only creates elements once in Strict Mode', () => {
test('only creates elements once in Strict Mode', () => {
const TestComponent = () => {
const _ = useElements();
return <div />;
Expand Down Expand Up @@ -83,39 +81,39 @@ describe('Elements', () => {
});

test('provides elements and stripe with the ElementsConsumer component', () => {
expect.assertions(2);
const spy = jest.fn()

render(
<Elements stripe={mockStripe}>
<ElementsConsumer>
{(ctx) => {
expect(ctx.elements).toBe(mockElements);
expect(ctx.stripe).toBe(mockStripe);

spy(ctx)
return null;
}}
</ElementsConsumer>
</Elements>
);

expect(spy).toBeCalledWith({ stripe: mockStripe, elements: mockElements });
});

test('provides elements and stripe with the ElementsConsumer component in Strict Mode', () => {
expect.assertions(2);
const spy = jest.fn()

render(
<React.StrictMode>
<Elements stripe={mockStripe}>
<ElementsConsumer>
{(ctx) => {
expect(ctx.elements).toBe(mockElements);
expect(ctx.stripe).toBe(mockStripe);

return null;
}}
</ElementsConsumer>
</Elements>
<Elements stripe={mockStripe}>
<ElementsConsumer>
{(ctx) => {
spy(ctx)
return null;
}}
</ElementsConsumer>
</Elements>
</React.StrictMode>
);

expect(spy).toBeCalledWith({ stripe: mockStripe, elements: mockElements });
});

test('provides given stripe instance on mount', () => {
Expand Down Expand Up @@ -159,8 +157,8 @@ describe('Elements', () => {
<React.StrictMode>
<Elements stripe={stripeProp}>
<ElementsConsumer>
{({stripe, elements}) => {
spy({stripe, elements});
{(ctx) => {
spy(ctx)
return null;
}}
</ElementsConsumer>
Expand Down
22 changes: 7 additions & 15 deletions src/components/Elements.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,6 @@ export const parseElementsContext = (
return ctx;
};

const createElementsContext = (stripe: stripeJs.Stripe | null, options?: stripeJs.StripeElementsOptions) => {
const elements = stripe ? stripe.elements(options) : null
return {
stripe,
elements
}
}

interface ElementsProps {
/**
* A [Stripe object](https://stripe.com/docs/js/initializing) or a `Promise` resolving to a `Stripe` object.
Expand Down Expand Up @@ -116,24 +108,24 @@ export const Elements: FunctionComponent<ElementsProps> = (props: PrivateElement
}, [inputs, props])

const [maybeStripe = null] = usePromiseResolver(inputs.rawStripe)
const resolvedStripe = validateStripe(maybeStripe)
const [ctx, setContext] = React.useState(() => createElementsContext(resolvedStripe, inputs.options));
const stripe = validateStripe(maybeStripe)
const [elements, setElements] = React.useState<stripeJs.StripeElements | null>(null);

const shouldInitialize = resolvedStripe !== null && ctx.stripe === null
React.useEffect(() => {
if (shouldInitialize) setContext(createElementsContext(resolvedStripe, inputs.options))
}, [shouldInitialize, resolvedStripe, inputs.options])
if (stripe) setElements(stripe ? stripe.elements(inputs.options) : null)
}, [stripe, inputs.options])

React.useEffect(() => {
const anyStripe: any = ctx.stripe;
const anyStripe: any = stripe;

if (!anyStripe || !anyStripe._registerWrapper) {
return;
}

anyStripe._registerWrapper({name: 'react-stripe-js', version: _VERSION});
}, [ctx.stripe]);
}, [stripe]);

const ctx: ElementsContextValue = { stripe, elements }
return (
<ElementsContext.Provider value={ctx}>{children}</ElementsContext.Provider>
);
Expand Down

0 comments on commit bd35e6d

Please sign in to comment.