Having issues with useDeliveryGroup trying to get if pickup is selected

jfeuchter_be
Shopify Partner
5 0 2
Hey Everyone, Im building a checkout ui extension where Im trying to use the useDeliveryGroup to call the selected delivery group to see if its the pickup. Ive tried to do it within the extension function setting it up under the reductions section. But the function is being rerendered too many times. If I try to put this in a useEffect function the useDeliveryGroup  Sees an issue of having a hook inside ofuseEffect. What could I do here to get the useDeliveryGroup  and if its pickup set a attribute and unset it if its not.Here is my sample code:
const [pickupState, setPickupState] = useState(false);

  useEffect( ()=>{
    const deliveryGroups = useDeliveryGroups();
    console.log("deliveryGroups",deliveryGroups);

    if (typeof deliveryGroups != 'undefined' && deliveryGroups.length > 0) {
      const {
        selectedDeliveryOption
      } = useDeliveryGroup(deliveryGroups[0]);
      console.log("selectedDeliveryOption",selectedDeliveryOption);
      console.log("inside deliveryGroups if statement");

      const setPickupAttribute = async () => {
        console.log("inside setPickupAttribute");
        const pickupAttribute = useAttributeValues(['pickup']);
        const updateAttribute = useApplyAttributeChange();

        if (typeof selectedDeliveryOption != 'undefined' && selectedDeliveryOption?.title === 'Pickup' && typeof pickupAttribute === 'undefined') {
          await updateAttribute({
            type: "updateAttribute",
            key: "pickup",
            value: "true",
          });
          setPickupState(true);
        } else {
          await updateAttribute({
            type: "updateAttribute",
            key: "pickup",
            value: "",
          });
          setPickupState(false);
        }
      }
    } else {
      console.log("No delivery groups found");
    }
  }, []);

  return (
    <Banner title="pickup-attribute">
      {pickupState && (
        <p>
          {selectedDeliveryOption ? selectedDeliveryOption?.title : "No selected Delivery Option"}
        </p>
      )}
      {pickupState ? 'Pickup is selected' : 'Pickup is not selected'}
    </Banner>
  );

 the render o the banner is just for testing in the future I will render an empty space. Cause I need this for a discount function Im building. 

 

Any ideas ? 😄 

Replies 3 (3)

Liam
Shopify Staff
2731 298 769

Hi Jfeuchter_be,

 

Based on your code, it seems that you're trying to use hooks inside useEffect which React doesn't allow. I'd recommend updating your code so that the hooks are called at top level of your React function.

 

Hope this helps,

Liam | Developer Advocate @ Shopify 
 - Was my reply helpful? Click Like to let me know! 
 - Was your question answered? Mark it as an Accepted Solution
 - To learn more visit Shopify.dev or the Shopify Web Design and Development Blog

jfeuchter_be
Shopify Partner
5 0 2

I've tried different approaches, if I take the code out of the useEffect. The code rerenders again and again when I select pickup and refreshe the page. 

 

import React, {useEffect, useState} from 'react';
import {
  Banner,
  useApi,
  useTranslate,
  reactExtension,
  useDeliveryGroups,
  useDeliveryGroup,
  useAttributeValues,
  useApplyAttributeChange,
} from '@shopify/ui-extensions-react/checkout';

export default reactExtension(
  'purchase.checkout.reductions.render-after',
  () => <Extension />,
);

function Extension() {
  const { deliveryGroups } = useApi();
  const [pickupState, setPickupState] = useState(false);

  //const deliveryGroups = useDeliveryGroups();
  //console.log("deliveryGroups",deliveryGroups.current);
  if (typeof deliveryGroups != 'undefined' && typeof deliveryGroups.current != 'undefined' && deliveryGroups.current.length > 0) {
    const selectedDeliveryOption = deliveryGroups.current[0].selectedDeliveryOption;
    console.log("selectedDeliveryOption", selectedDeliveryOption);
    console.log("inside deliveryGroups if statement");

    console.log("inside setPickupAttribute");
    const pickupAttribute = useAttributeValues(['pickup']);
    console.log('pickupAttribute', pickupAttribute);
    const updateAttribute = useApplyAttributeChange();

    if (typeof selectedDeliveryOption != 'undefined' && selectedDeliveryOption?.title === 'Pickup' && typeof pickupAttribute === 'undefined') {
      if (typeof pickupAttribute != 'undefined' && pickupAttribute === '') {
        const setPickupAttribute = async () => {
          await updateAttribute({
            type: "updateAttribute",
            key: "pickup",
            value: "true",
          });
        }
      }
      setPickupState(true);
    } else {
      if (typeof pickupAttribute != 'undefined' && pickupAttribute === 'true') {
        const setPickupAttribute = async () => {
          await updateAttribute({
            type: "updateAttribute",
            key: "pickup",
            value: "",
          });
        }
      }
      setPickupState(false);
    }
  } else {
    console.log("No delivery groups found");
  }
  
  return (
    <Banner title="pickup-attribute">
      {pickupState ? 'Pickup is selected' : 'Pickup is not selected'}
    </Banner>
  );
}

 

Any Ideas why this might be? I thought maybe because the updateAttribute was triggering rerender, but even if I try to get the attribute to check it and only change it if its different it does not work either 😧 

RobFarmLink
Shopify Partner
32 2 23

I'm guessing this Shopify bug is causing you to try this workaround as it did for me. Check out a workaround there, but it'd be great if someone from Shopify could give this one a little more light.