I am fetching data from AWS DataStore and there is an infinite loop when fetching the cart item data from the DataStore. I don't know where this loop came from. I tried to wrap fetchCartItems function with useCallback, also removed the dependencies from the useEffect hook but nothing changed. I get this infinite loop when I console log the cartProducts.
This is the cart item context
import React, {
useState,
useEffect,
useContext,
createContext,
useCallback,
} from "react";
import { DataStore } from "aws-amplify";
import { CartItems } from "../src/models";
import { useAuthContext } from "./AuthContext";
const CartContext = createContext({});
const CartContextProvider = ({ children }) => {
const [cartProducts, setCartProducts] = useState([]);
const { authUser } = useAuthContext();
const [quantity, setQuantity] = useState("");
// console.log(cartProducts)
const addToCart = async (item) => {
try {
const foundCartItem = await DataStore.query(CartItems, (i) =>
i.productId("eq", item.id)
);
if (foundCartItem.length === 0) {
await DataStore.save(
new CartItems({
userId: authUser.attributes.sub,
productId: item.id,
productPrice: item.price,
productTitle: item.title,
productImage: item.image,
quantity: quantity,
})
);
} else {
return;
}
} catch (error) {
console.log("Error is: ", error);
}
};
const fetchCartItems = async () => {
try {
const cartData = await DataStore.query(CartItems, (user) =>
user.userId("eq", authUser.attributes.sub)
);
setCartProducts(cartData);
} catch (error) {
console.log("Error: ", error);
}
};
useEffect(() => {
fetchCartItems();
}),
[addToCart, quantity];
return (
<CartContext.Provider
value={{
cartProducts,
setCartProducts,
addToCart,
quantity,
setQuantity,
}}
>
{children}
</CartContext.Provider>
);
};
export default CartContextProvider;
export const useCartContext = () => useContext(CartContext);
This is the cart item screen
import React from "react";
import {
View,
Text,
Image,
StyleSheet,
FlatList,
TouchableOpacity,
} from "react-native";
import ItemQuantity from "../../component/ItemQuantity";
import Colors from "../../constants/Colors";
import { useCartContext } from "../../contexts/CartContext";
const CartItem = () => {
const { cartProducts } = useCartContext();
return (
<View style={styles.screen}>
<FlatList
data={cartProducts}
renderItem={({ item }) => {
return (
<View style={styles.container}>
<View style={styles.cardView}>
<View style={styles.imageView}>
<Image
style={styles.image}
source={{ uri: item.productImage }}
/>
</View>
<View style={styles.detailsView}>
<Text style={styles.titl}>{item.productTitle}</Text>
<Text style={styles.price}>{item.productPrice} ج.م </Text>
</View>
</View>
<ItemQuantity
updatedItemId={item.id}
quantityItem={item.quantity}
/>
</View>
);
}}
/>
</View>
);
};
const styles = StyleSheet.create({
screen: {
margin: 20,
},
});
The issue here is that you put your useEffect
's dependencies after initialising the hook.
useEffect(() => {
fetchCartItems();
}),
[addToCart, quantity];
fetchCartItems
is being called with every render, because the hook has no dependencies (not even an empty array making it be called once), and on every call it edits the state, rerendering the dom and calling itself again.
addToCart
shouldn't be in your useEffect
's dependencies, as it as function that you don't ever change in your code. Try:
useEffect(() => {
fetchCartItems();
}, [quantity]);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.