简体   繁体   中英

Infinite loop when querying data from aws dataStore using react native

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM