woocommerce/plugins/woocommerce-blocks/assets/js/base/hooks/shipping/use-shipping-address.js

57 lines
1.8 KiB
JavaScript

/**
* External dependencies
*/
import { useDispatch } from '@wordpress/data';
import { useEffect, useState } from '@wordpress/element';
import isShallowEqual from '@wordpress/is-shallow-equal';
import { useDebounce } from 'use-debounce';
import { CART_STORE_KEY as storeKey } from '@woocommerce/block-data';
import { decodeEntities } from '@wordpress/html-entities';
/**
* Internal dependencies
*/
import { useStoreCart } from '../cart/use-store-cart';
import { useStoreNotices } from '../use-store-notices';
import { pluckAddress } from '../../utils';
const shouldUpdateStore = ( oldAddress, newAddress ) =>
! isShallowEqual( pluckAddress( oldAddress ), pluckAddress( newAddress ) );
export const useShippingAddress = () => {
const { shippingAddress: initialAddress } = useStoreCart();
const [ shippingAddress, setShippingAddress ] = useState( initialAddress );
const [ debouncedShippingAddress ] = useDebounce( shippingAddress, 400 );
const { updateShippingAddress } = useDispatch( storeKey );
const { addErrorNotice } = useStoreNotices();
// Note, we're intentionally not using initialAddress as a dependency here
// so that the stale (previous) value is being used for comparison.
useEffect( () => {
if (
debouncedShippingAddress.country &&
shouldUpdateStore( initialAddress, debouncedShippingAddress )
) {
updateShippingAddress( debouncedShippingAddress ).catch(
( error ) => {
addErrorNotice( error.message, {
id: 'shipping-form',
} );
}
);
}
}, [ debouncedShippingAddress ] );
const decodedShippingAddress = {};
Object.keys( shippingAddress ).forEach( ( key ) => {
decodedShippingAddress[ key ] = decodeEntities(
shippingAddress[ key ]
);
} );
return {
shippingAddress: decodedShippingAddress,
setShippingAddress,
};
};