Search code examples
reactjstypescriptnativeasyncstorage

Issue with React Native AsyncStorage and updating state with new data


I'm facing an issue with managing data retrieval from AsyncStorage in my React Native application. I'm using AsyncStorage to store orders, and I want to dynamically update my component whatever a new order is added to AsyncStorage. However, I do not know how to this

`

import React, { useEffect, useState } from "react";
import { View } from "react-native";
import AsyncStorage from "@react-native-async-storage/async-storage";
import CartItems from "../../../components/cartItems";

function CartPage() {
  let order = [];

  async function getCartData() {
    try {
      const orderDataFromStorage = await AsyncStorage.getItem("order");
      if (orderDataFromStorage) {
        const parsedData = JSON.parse(orderDataFromStorage);
        order.push(parsedData)
        AsyncStorage.removeItem("order");
      }
    } catch (error) {
      console.log(error);
    }
  }

  useEffect(() => {getCartData}, [])

  return (
    <View>
      <CartItems orders={order} />
    </View>
  );
}

export default CartPage;


Issue: The problem I'm facing is that I don't know how to dynamically update my CartPage component whatever a new order is added to AsyncStorage. Currently, my component does not reflect the new data.

Desired Outcome: I want the CartPage component to update and display all orders, including any newly added ones, dynamically whenever a new order is added to AsyncStorage.

What I've Tried: I've used the getCartData function inside a useEffect hook to retrieve data from AsyncStorage, but it doesn't seem to update the component correctly.

Additional Information: The structure of data saved in AsyncStorage is JSON formatted as { "chosedAddon": [], "order": ["Tom & Jerry", "Fries, mozzarella, tomato"], "price": 8, "quantity": 1 }.é.


Solution

  • From your example the useEffect will only run once, on initial load. The second parameter [] needs to have:

    • useEffect(() => {... logic}) - runs on every render
    • useEffect(() => {... logic}, []) - runs once on component load
    • useEffect(() => {... logic}, [ dependencies e.g. order]) - runs every time this value changes.

    I would also use useState on the order to keep track of changes.

    So the changes could be

    import React, { useEffect, useState } from "react";
    import { View } from "react-native";
    import AsyncStorage from "@react-native-async-storage/async-storage";
    import CartItems from "../../../components/cartItems";
    
    function CartPage() {
      const [order, setOrder] = useState([]);
    
      async function getCartData() {
        try {
          const orderDataFromStorage = await AsyncStorage.getItem("order");
          if (orderDataFromStorage) {
            const parsedData = JSON.parse(orderDataFromStorage);
            order.push(parsedData)
            AsyncStorage.removeItem("order");
          }
        } catch (error) {
          console.log(error);
        }
      }
    
      useEffect(() => {await getCartData()}, [order])
    
      return (
        <View>
          <CartItems orders={order} />
        </View>
      );
    }
    
    export default CartPage;