diff --git a/src/components/EmbeddedCheckout.client.test.tsx b/src/components/EmbeddedCheckout.client.test.tsx
index 0ac2b45..a6749bd 100644
--- a/src/components/EmbeddedCheckout.client.test.tsx
+++ b/src/components/EmbeddedCheckout.client.test.tsx
@@ -129,4 +129,29 @@ describe('EmbeddedCheckout on the client', () => {
);
expect(mockEmbeddedCheckout.unmount).toBeCalled();
});
+
+ it('does not throw when the Embedded Checkout instance is already destroyed when unmounting', async () => {
+ const {container, rerender} = render(
+
+
+
+ );
+
+ await act(() => mockEmbeddedCheckoutPromise);
+
+ expect(mockEmbeddedCheckout.mount).toBeCalledWith(container.firstChild);
+
+ mockEmbeddedCheckout.unmount.mockImplementation(() => {
+ throw new Error('instance has been destroyed');
+ });
+
+ expect(() => {
+ rerender(
+
+ );
+ }).not.toThrow();
+ });
});
diff --git a/src/components/EmbeddedCheckout.tsx b/src/components/EmbeddedCheckout.tsx
index cf0db84..337aadc 100644
--- a/src/components/EmbeddedCheckout.tsx
+++ b/src/components/EmbeddedCheckout.tsx
@@ -32,8 +32,17 @@ const EmbeddedCheckoutClientElement = ({
// Clean up on unmount
return () => {
if (isMounted.current && embeddedCheckout) {
- embeddedCheckout.unmount();
- isMounted.current = false;
+ try {
+ embeddedCheckout.unmount();
+ isMounted.current = false;
+ } catch (e) {
+ // Do nothing.
+ // Parent effects are destroyed before child effects, so
+ // in cases where both the EmbeddedCheckoutProvider and
+ // the EmbeddedCheckout component are removed at the same
+ // time, the embeddedCheckout instance will be destroyed,
+ // which causes an error when calling unmount.
+ }
}
};
}, [embeddedCheckout]);