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