diff --git a/assets/js/blocks/cart-checkout-shared/payment-methods/express-payment-methods.js b/assets/js/blocks/cart-checkout-shared/payment-methods/express-payment-methods.js index c30fa050be1..89bdc3296af 100644 --- a/assets/js/blocks/cart-checkout-shared/payment-methods/express-payment-methods.js +++ b/assets/js/blocks/cart-checkout-shared/payment-methods/express-payment-methods.js @@ -141,17 +141,23 @@ const ExpressPaymentMethods = () => { const expressPaymentMethod = isEditor ? paymentMethod.edit : paymentMethod.content; + const expressPaymentMethodId = paymentMethod.name; return isValidElement( expressPaymentMethod ) ? ( -
  • - { cloneElement( expressPaymentMethod, { - ...paymentMethodInterface, - onClick: onExpressPaymentClick( id ), - onClose: onExpressPaymentClose, - onError: onExpressPaymentError, - setExpressPaymentError: - deprecatedSetExpressPaymentError, - } ) } -
  • + +
  • + { cloneElement( expressPaymentMethod, { + ...paymentMethodInterface, + onClick: onExpressPaymentClick( id ), + onClose: onExpressPaymentClose, + onError: onExpressPaymentError, + setExpressPaymentError: + deprecatedSetExpressPaymentError, + } ) } +
  • +
    ) : null; } ) ) : ( @@ -164,11 +170,9 @@ const ExpressPaymentMethods = () => { ); return ( - - - + ); }; diff --git a/assets/js/blocks/cart-checkout-shared/payment-methods/payment-method-error-boundary.tsx b/assets/js/blocks/cart-checkout-shared/payment-methods/payment-method-error-boundary.tsx index 6f43e7de18a..fc5d83cb469 100644 --- a/assets/js/blocks/cart-checkout-shared/payment-methods/payment-method-error-boundary.tsx +++ b/assets/js/blocks/cart-checkout-shared/payment-methods/payment-method-error-boundary.tsx @@ -2,51 +2,77 @@ * External dependencies */ import { __ } from '@wordpress/i18n'; -import { useState } from '@wordpress/element'; +import { Component } from '@wordpress/element'; import { CURRENT_USER_IS_ADMIN } from '@woocommerce/settings'; import { StoreNoticesContainer } from '@woocommerce/blocks-components'; import { noticeContexts } from '@woocommerce/base-context'; import { NoticeType } from '@woocommerce/types'; +import { + DerivedStateReturn, + ReactError, +} from '@woocommerce/base-components/block-error-boundary/types'; +import { __experimentalDeRegisterExpressPaymentMethod } from '@woocommerce/blocks-registry'; + interface PaymentMethodErrorBoundaryProps { isEditor: boolean; children: React.ReactNode; + expressPaymentMethodId: string | undefined; } -const PaymentMethodErrorBoundary = ( { - isEditor, - children, -}: PaymentMethodErrorBoundaryProps ) => { - const [ errorMessage ] = useState( '' ); - const [ hasError ] = useState( false ); - if ( hasError ) { - let errorText = __( - 'We are experiencing difficulties with this payment method. Please contact us for assistance.', - 'woo-gutenberg-products-block' - ); - if ( isEditor || CURRENT_USER_IS_ADMIN ) { - if ( errorMessage ) { - errorText = errorMessage; - } else { - errorText = __( - "There was an error with this payment method. Please verify it's configured correctly.", - 'woo-gutenberg-products-block' + +class PaymentMethodErrorBoundary extends Component< PaymentMethodErrorBoundaryProps > { + state = { errorMessage: '', hasError: false }; + expressPaymentMethodId = this.props.expressPaymentMethodId; + static getDerivedStateFromError( error: ReactError ): DerivedStateReturn { + return { + errorMessage: error.message, + hasError: true, + }; + } + + render() { + const { hasError, errorMessage } = this.state; + const { isEditor } = this.props; + + if ( hasError ) { + let errorText = __( + 'We are experiencing difficulties with this payment method. Please contact us for assistance.', + 'woo-gutenberg-products-block' + ); + if ( isEditor || CURRENT_USER_IS_ADMIN ) { + if ( errorMessage ) { + errorText = errorMessage; + } else { + errorText = __( + "There was an error with this payment method. Please verify it's configured correctly.", + 'woo-gutenberg-products-block' + ); + } + } + const notices: NoticeType[] = [ + { + id: '0', + content: errorText, + isDismissible: false, + status: 'error', + }, + ]; + + // De-register the express payment method if has an error. + if ( this.expressPaymentMethodId !== undefined ) { + __experimentalDeRegisterExpressPaymentMethod( + this.expressPaymentMethodId ); } + + return ( + + ); } - const notices: NoticeType[] = [ - { - id: '0', - content: errorText, - isDismissible: false, - status: 'error', - }, - ]; - return ( - - ); + + return this.props.children; } - return <>{ children }; -}; +} export default PaymentMethodErrorBoundary;