0

In my deleteOrSubstractQuantity when the first if statement gets called where I set the quantity to 0 essentially deleting the item's quantity and the "expanded view" closes the quantity in the de-expanded view is shown as 0 and after a second or two it shows the correct "+" sign. Here's my code in the UI that does this: When the quantity is bigger or equal to minOrderQuantity it should show the quantity in the circle, or else it mush show a "+" sign

quantity >= minOrderQuantity ? (
  <Text
    style={{
      color: "black",
      fontSize: 12,
      fontWeight: "300",
    }}
  >
    {quantity} {item.uom == "UNIT" ? "Ct" : item.uom}
  </Text>
) : (
  <AntDesign name="plus" size={20} color="black" />
);

I want the update to be instant, when I delete the quantity it should show the "+" sign without any waiting

Here's my entire code

import React, { useCallback, useEffect, useRef, useState } from "react";
import { Animated, Image, Text, TouchableOpacity, View } from "react-native";
import { responsiveWidth } from "react-native-responsive-dimensions";
import { AntDesign, SimpleLineIcons } from "@expo/vector-icons";

import { text } from "../../text";
import { theme } from "../../constants";
import { Product } from "../../types";
import { useAppDispatch } from "../../hooks";
import { addToCart } from "../../store/slices/cartSlice";

type Props = {
  item: Product;
};

const ProductItem: React.FC<Props> = ({ item }): JSX.Element | null => {
  const dispatch = useAppDispatch();

  const blockWidth = responsiveWidth(100) / 2 - 30;
  const blockHeight = responsiveWidth(100) / 2;

  const minOrderQuantity = item.minOrderQuantity;
  const maxOrderQuantity = item.maxOrderQuantity;

  const [expanded, setExpanded] = useState(false);
  const [quantity, setQuantity] = useState(0);
  const [smallBufferLoad, setsSmallBufferLoad] = useState(false);

  const addBtnWidth = 36;
  const addBtnHeight = 36;

  const leftDefaultValue = 120;

  const widthAnim = useRef(new Animated.Value(addBtnWidth)).current;
  const leftAnim = useRef(new Animated.Value(leftDefaultValue)).current;

  const timer = useRef<NodeJS.Timeout | null>(null);

  const openAnimation = () => {
    Animated.parallel([
      Animated.timing(widthAnim, {
        toValue: expanded ? addBtnWidth : blockWidth,
        duration: 200,
        useNativeDriver: false,
      }),
      Animated.timing(leftAnim, {
        toValue: expanded ? 100 : 0,
        duration: 200,
        useNativeDriver: false,
      }),
    ]).start();
  };

  const closeAnimation = () => {
    Animated.parallel([
      Animated.timing(widthAnim, {
        toValue: addBtnWidth,
        duration: 200,
        useNativeDriver: false,
      }),
      Animated.timing(leftAnim, {
        toValue: leftDefaultValue,
        duration: 200,
        useNativeDriver: false,
      }),
    ]).start();
  };

  const setNewCloseTimeout = (timeoutInterval: number = 2000) => {
    timer.current = setTimeout(() => {
      setExpanded(false);
      closeAnimation();
    }, timeoutInterval);
  };

  const toggleExpand = () => {
    // Set quantity to the minimum order quantity possible once the plus sign is selected
    if (quantity == 0) {
      setQuantity(minOrderQuantity);
    }
    setExpanded(!expanded);
    openAnimation();
  };

  const resetTimeout = (timeoutInterval: number = 2000) => {
    clearCurrentTimeout();
    setNewCloseTimeout(timeoutInterval);
  };

  const clearCurrentTimeout = useCallback(() => {
    if (timer.current) {
      clearTimeout(timer.current);
      timer.current = null;
    }
  }, []);

  useEffect(() => {
    if (expanded) {
      resetTimeout(1500);
    }
    return () => {
      clearCurrentTimeout();
    };
  }, [expanded]);

  // useEffect(() => {
  //     if (quantity > 0) {
  //         dispatch(addToCart({
  //             product: item,
  //             quantity,
  //         }));
  //     }
  // }, [quantity, dispatch, item]);

  const addQuantity = () => {
    resetTimeout();
    const newQuantity = quantity + 1;
    setQuantity(
      newQuantity > maxOrderQuantity ? maxOrderQuantity : newQuantity,
    );
    // dispatch(addToCart({
    //     product: item,
    //     quantity: newQuantity,
    // }));
  };

  const deleteOrSubtractQuantity = () => {
    resetTimeout();
    if (quantity == minOrderQuantity) {
      // Delete
      setQuantity(0);
      setsSmallBufferLoad(true);
      closeAnimation();
      setTimeout(() => {
        setsSmallBufferLoad(false);
      }, 300);
    } else {
      // Subtract
      const newQuantity = quantity - 1;
      setQuantity(
        minOrderQuantity < newQuantity ? newQuantity : minOrderQuantity,
      );
    }
  };

  return (
    <TouchableOpacity
      onPress={toggleExpand}
      activeOpacity={0.96}
      style={{
        width: blockWidth,
        height: blockHeight,
        borderRadius: 24,
        paddingHorizontal: 14,
        paddingTop: 14,
        paddingBottom: 12,
        justifyContent: "space-between",
        position: "relative",
        borderWidth: 0.4,
        borderColor: "lightgray",
        marginBottom: 8,
      }}
    >
      <Animated.View
        style={{
          position: "absolute",
          left: leftAnim,
          bottom: "8%",
          width: widthAnim,
          height: addBtnHeight,
          backgroundColor: theme.colors.white,
          transform: [{ translateY: -45 }],
          zIndex: 1,
          borderRadius: 25,
          alignItems: "center",
          justifyContent: "center",
          shadowColor: "#000",
          shadowOffset: {
            width: 0,
            height: 1,
          },
          shadowOpacity: 0.22,
          shadowRadius: 2.22,
          elevation: 3,
        }}
      >
        <TouchableOpacity onPress={toggleExpand}>
          {!expanded ? (
            quantity >= minOrderQuantity ? (
              <Text
                style={{
                  color: "black",
                  fontSize: 12,
                  fontWeight: "300",
                }}
              >
                {quantity} {item.uom == "UNIT" ? "Ct" : item.uom}
              </Text>
            ) : (
              <AntDesign name="plus" size={20} color="black" />
            )
          ) : (
            <View
              style={{
                flexDirection: "row",
                justifyContent: "space-between",
                width: "100%",
                paddingHorizontal: 12,
              }}
            >
              <TouchableOpacity
                onPress={deleteOrSubtractQuantity}
                style={{ justifyContent: "flex-start", padding: 6 }}
              >
                {quantity == minOrderQuantity ? (
                  <SimpleLineIcons name="trash" size={20} color="black" />
                ) : (
                  <AntDesign name="minus" size={20} color="black" />
                )}
              </TouchableOpacity>
              <View style={{ justifyContent: "center", alignItems: "center" }}>
                <Text
                  style={{
                    color: "black",
                    fontSize: 14,
                    fontWeight: "300",
                    textTransform: "capitalize",
                  }}
                >
                  {quantity} {item.uom}
                </Text>
              </View>
              <TouchableOpacity
                onPress={addQuantity}
                style={{ justifyContent: "flex-end", padding: 6 }}
              >
                <AntDesign
                  name="plus"
                  size={20}
                  disabled={quantity < maxOrderQuantity}
                  color={quantity >= maxOrderQuantity ? "lightgrey" : "black"}
                />
              </TouchableOpacity>
            </View>
          )}
        </TouchableOpacity>
      </Animated.View>
      <Image
        source={{ uri: item.image.formats.large.url }}
        style={{ flex: 1 }}
        resizeMode="contain"
      />
      <View style={{ alignItems: "flex-start" }}>
        <text.T16 numberOfLines={1}>{item.name}</text.T16>
      </View>
      <View style={{ alignItems: "flex-start" }}>
        <text.T14 numberOfLines={1}>
          {item.price} {item.currencyCode} / {item.uom}
        </text.T14>
      </View>
    </TouchableOpacity>
  );
};

export default ProductItem;

Here's what it looks like once I delete the quantity

enter image description here

0

Browse other questions tagged or ask your own question.