Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Checkout: Modify useCreateExistingCards to only rememoize only when ids change #49057

Merged
merged 1 commit into from
Feb 1, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* External dependencies
*/
import { useMemo } from 'react';
import { useMemo, useRef, useEffect } from 'react';
import {
createPayPalMethod,
createAlipayMethod,
Expand Down Expand Up @@ -288,22 +288,56 @@ function useCreateApplePay( {
return applePayMethod;
}

// See https://usehooks.com/useMemoCompare/
function useMemoCompare( next, compare ) {
// Ref for storing previous value
const previousRef = useRef();
const previous = previousRef.current;

// Pass previous and next value to compare function
// to determine whether to consider them equal.
const isEqual = compare( previous, next );

// If not equal update previousRef to next value.
// We only update if not equal so that this hook continues to return
// the same old value if compare keeps returning true.
useEffect( () => {
if ( ! isEqual ) {
previousRef.current = next;
}
} );

// Finally, if equal then return the previous value
return isEqual ? previous : next;
}

export function useCreateExistingCards( { storedCards, activePayButtonText = undefined } ) {
// Memoize the cards by comparing their stored_details_id values, in case the
// objects are recreated on each render.
const memoizedStoredCards = useMemoCompare( storedCards, ( prev, next ) => {
const prevIds = prev?.map( ( card ) => card.stored_details_id ) ?? [];
const nextIds = next?.map( ( card ) => card.stored_details_id ) ?? [];
return (
prevIds.length === nextIds.length && prevIds.every( ( id, index ) => id === nextIds[ index ] )
);
} );
const existingCardMethods = useMemo( () => {
return storedCards.map( ( storedDetails ) =>
createExistingCardMethod( {
id: `existingCard-${ storedDetails.stored_details_id }`,
cardholderName: storedDetails.name,
cardExpiry: storedDetails.expiry,
brand: storedDetails.card_type,
last4: storedDetails.card,
storedDetailsId: storedDetails.stored_details_id,
paymentMethodToken: storedDetails.mp_ref,
paymentPartnerProcessorId: storedDetails.payment_partner,
activePayButtonText,
} )
return (
memoizedStoredCards?.map( ( storedDetails ) =>
createExistingCardMethod( {
id: `existingCard-${ storedDetails.stored_details_id }`,
cardholderName: storedDetails.name,
cardExpiry: storedDetails.expiry,
brand: storedDetails.card_type,
last4: storedDetails.card,
storedDetailsId: storedDetails.stored_details_id,
paymentMethodToken: storedDetails.mp_ref,
paymentPartnerProcessorId: storedDetails.payment_partner,
activePayButtonText,
} )
) ?? []
);
}, [ storedCards, activePayButtonText ] );
}, [ memoizedStoredCards, activePayButtonText ] );
return existingCardMethods;
}

Expand Down