Trigger fragment refresh after editing cart item quantities (https://github.com/woocommerce/woocommerce-blocks/pull/2266)

* Make util to fire legacy events

* Update button to use util

* Trigger event when quantity changes

* Trigger event on removal

* Move comments to util
This commit is contained in:
Mike Jolley 2020-04-24 14:41:32 +01:00 committed by GitHub
parent 7f85c1bcc0
commit 8bf58b4596
4 changed files with 36 additions and 20 deletions

View File

@ -8,8 +8,7 @@ import { useEffect, useRef } from '@wordpress/element';
import { useStoreAddToCart } from '@woocommerce/base-hooks';
import { useProductLayoutContext } from '@woocommerce/base-context';
import { decodeEntities } from '@wordpress/html-entities';
const Event = window.Event || null;
import { triggerFragmentRefresh } from '@woocommerce/base-utils';
const ProductButton = ( { product, className } ) => {
const {
@ -28,7 +27,6 @@ const ProductButton = ( { product, className } ) => {
} = useStoreAddToCart( id );
const { layoutStyleClassPrefix } = useProductLayoutContext();
const addedToCart = Number.isFinite( cartQuantity ) && cartQuantity > 0;
const firstMount = useRef( true );
const getButtonText = () => {
if ( addedToCart ) {
return sprintf(
@ -45,26 +43,15 @@ const ProductButton = ( { product, className } ) => {
return decodeEntities( productCartDetails.text );
};
// This is a hack to trigger cart updates till we migrate to block based cart
// that relies on the store, see
// https://github.com/woocommerce/woocommerce-gutenberg-products-block/issues/1247
const firstMount = useRef( true );
useEffect( () => {
// Avoid running on first mount when cart quantity is first set.
if ( firstMount.current ) {
firstMount.current = false;
return;
}
// In IE, Event is an object and can't be instantiated with `new Event()`.
if ( typeof Event === 'function' ) {
const event = new Event( 'wc_fragment_refresh', {
bubbles: true,
cancelable: true,
} );
document.body.dispatchEvent( event );
} else {
const event = document.createEvent( 'Event' );
event.initEvent( 'wc_fragment_refresh', true, true );
document.body.dispatchEvent( event );
}
triggerFragmentRefresh();
}, [ cartQuantity ] );
const wrapperClasses = classnames(

View File

@ -7,6 +7,7 @@ import { CART_STORE_KEY as storeKey } from '@woocommerce/block-data';
import { usePrevious } from '@woocommerce/base-hooks';
import { useDebounce } from 'use-debounce';
import { useCheckoutContext } from '@woocommerce/base-context';
import { triggerFragmentRefresh } from '@woocommerce/base-utils';
/**
* Internal dependencies
@ -66,17 +67,25 @@ export const useStoreCartItemQuantity = ( cartItem ) => {
},
[ cartItemKey ]
);
const removeItem = () => {
return cartItemKey ? removeItemFromCart( cartItemKey ) : false;
return cartItemKey
? removeItemFromCart( cartItemKey ).then( () => {
triggerFragmentRefresh();
} )
: false;
};
// Observe debounced quantity value, fire action to update server on change.
useEffect( () => {
// Don't run it if quantity didn't change but it was set for the first time.
if ( cartItemKey && Number.isFinite( previousDebouncedQuantity ) ) {
changeCartItemQuantity( cartItemKey, debouncedQuantity );
changeCartItemQuantity( cartItemKey, debouncedQuantity ).then(
triggerFragmentRefresh
);
}
}, [ debouncedQuantity, cartItemKey ] );
useEffect( () => {
if ( isPendingQuantity ) {
dispatchActions.incrementCalculating();

View File

@ -2,3 +2,4 @@ export * from './errors';
export * from './price';
export * from './address';
export * from './shipping-rates';
export * from './legacy-events';

View File

@ -0,0 +1,19 @@
const Event = window.Event || null;
// This is a hack to trigger cart updates till we migrate to block based cart
// that relies on the store, see
// https://github.com/woocommerce/woocommerce-gutenberg-products-block/issues/1247
export const triggerFragmentRefresh = () => {
// In IE, Event is an object and can't be instantiated with `new Event()`.
if ( typeof Event === 'function' ) {
const event = new Event( 'wc_fragment_refresh', {
bubbles: true,
cancelable: true,
} );
document.body.dispatchEvent( event );
} else {
const event = document.createEvent( 'Event' );
event.initEvent( 'wc_fragment_refresh', true, true );
document.body.dispatchEvent( event );
}
};