diff --git a/src/usePlaidLink.ts b/src/usePlaidLink.ts index 087368b3..ebe684d8 100644 --- a/src/usePlaidLink.ts +++ b/src/usePlaidLink.ts @@ -1,4 +1,4 @@ -import { useEffect, useState } from 'react'; +import { useEffect, useMemo, useState } from 'react'; import useScript from 'react-script-hook'; import { createPlaid, PlaidFactory } from './factory'; @@ -29,14 +29,13 @@ export const usePlaidLink = (options: PlaidLinkOptions) => { }); // internal state - const [plaid, setPlaid] = useState(null); const [iframeLoaded, setIframeLoaded] = useState(false); const products = ((options as PlaidLinkOptionsWithPublicKey).product || []) .slice() .sort() .join(','); - useEffect(() => { + const plaid = useMemo((): PlaidFactory | void => { // If the link.js script is still loading, return prematurely if (loading) { return; @@ -57,27 +56,16 @@ export const usePlaidLink = (options: PlaidLinkOptions) => { return; } - // if an old plaid instance exists, destroy it before - // creating a new one - if (plaid != null) { - plaid.exit({ force: true }, () => plaid.destroy()); - } - - const next = createPlaid( + return createPlaid( { ...options, onLoad: () => { - setIframeLoaded(true); + setIframeLoaded(false); options.onLoad && options.onLoad(); }, }, window.Plaid.create ); - - setPlaid(next); - - // destroy the Plaid iframe factory - return () => next.exit({ force: true }, () => next.destroy()); }, [ loading, error, @@ -86,7 +74,18 @@ export const usePlaidLink = (options: PlaidLinkOptions) => { products, ]); - const ready = plaid != null && (!loading || iframeLoaded); + useEffect(() => { + setIframeLoaded(false); + if (!plaid) { + return; + } + return () => { + // destroy the Plaid iframe factory when unmounting an instance + plaid.exit({ force: true }, () => plaid.destroy()); + } + }, [plaid]) + + const ready = !!plaid && !loading && iframeLoaded; const openNoOp = () => { if (!options.token) {