woocommerce/plugins/woocommerce-blocks/assets/js/base/hooks/payment-methods/use-payment-methods.js

60 lines
1.8 KiB
JavaScript

/**
* External dependencies
*/
import {
getPaymentMethods,
getExpressPaymentMethods,
} from '@woocommerce/blocks-registry';
import { useState, useEffect, useRef } from '@wordpress/element';
const usePaymentMethodState = ( registeredPaymentMethods ) => {
const [ paymentMethods, setPaymentMethods ] = useState( [] );
const [ isInitialized, setIsInitialized ] = useState( false );
const countPaymentMethodsInitializing = useRef(
Object.keys( registeredPaymentMethods ).length
);
useEffect( () => {
// if all payment methods are initialized then bail.
if ( isInitialized ) {
return;
}
// loop through payment methods and see what the state is
for ( const paymentMethodId in registeredPaymentMethods ) {
const current = registeredPaymentMethods[ paymentMethodId ];
current.canMakePayment
.then( ( canPay ) => {
if ( canPay ) {
setPaymentMethods( ( previousPaymentMethods ) => {
return {
...previousPaymentMethods,
[ current.id ]: current,
};
} );
}
// update the initialized count
countPaymentMethodsInitializing.current--;
// if count remaining less than 1, then set initialized.
if ( countPaymentMethodsInitializing.current < 1 ) {
setIsInitialized( true );
}
} )
.catch( ( error ) => {
// @todo, would be a good place to use the checkout error
// hooks here? Or maybe throw and catch by error boundary?
throw new Error(
'Problem with payment method initialization' +
( error.message || '' )
);
} );
}
}, [ isInitialized ] );
return { paymentMethods, isInitialized };
};
export const usePaymentMethods = () =>
usePaymentMethodState( getPaymentMethods() );
export const useExpressPaymentMethods = () =>
usePaymentMethodState( getExpressPaymentMethods() );