Home > Software engineering >  Putting an object in an array AFTER it's loaded, React Native
Putting an object in an array AFTER it's loaded, React Native

Time:12-29

I'm trying to put an object into an array with an async function but the array is filled earlier than the object is loaded thus putting an empty object inside of the array.

import React, { useState, useEffect } from 'react';
import { StyleSheet, View, Button, FlatList, Image, Text, Pressable } from 'react-native';
import { useNavigation } from '@react-navigation/native';
import AsyncStorage from '@react-native-async-storage/async-storage';


import ShoppingCart from '../components/CartItem';


const CartScreen = ({ navigation, route }) => {

  const [newItem, setNewItem] = useState([]);
  const [cartItems, setCartItems] = useState([]);
  
  const getData = async () => {
    try{
      AsyncStorage.getItem('@cartItem')
      .then((value) => {
        if (value != null) {
          let itemdata = JSON.parse(value);
          setNewItem(itemdata);
          setCartItems((currentItems) => [...currentItems, newItem]);
        }
      })
    } catch (error) {
      console.log(error);
    }
  }

  useEffect(() => {
    getData();
  }, []);



  return(

  <View style={styles.screen}>

    <Pressable onPress={() => {
      console.log(newItem);
      console.log(newItem.itemID);
      console.log(cartItems);
    }}>
      <ShoppingCart title={newItem.itemID}/>
    </Pressable>

    <FlatList
      keyExtractor={item => item.itemID}
      data={cartItems}
      renderItem={(item) => (
        <ShoppingCart
        title={item.item.itemTitle}
        />
        )}
    
    />

  </View>

  );

}

In this code you can see I parse the string from @cartItem into newItem.

(I made a button on the screen to console.log and I can see that the data is correctly inside of newItem. ) saving the file and pressing the log button once

Then I put this newItem inside of cartItems, which is an array that acts as the data for my flatlist with shoppingcart items. This is where the funny thing happens. It first puts an empty array inside of cartItems, which I guess happens because newItem hasn't gotten its loaded data from the AsyncStorage yet. Now when I ctrl s to save this file (DetailsScreen.js) it updates (because of the useEffect I suppose) and puts the newItem correctly into cartItems but now there's an empty array and the right object in my flatlist. when getting on the screen and pressing the button to log

How can I make sure that newItem has gotten its value first before it gets put inside of cartItems? Or is this not the problem at all?

I have tried to use

  useEffect(() => {
    getData();
  }, [newItem]);

which makes an infiniteloop because it keeps updating, same for replacing newItem with cartItems.

I also notice there's some weird stuff going around with my flatlist where I have to put item.item.itemTitle instead of item.itemTitle, if anyone knows what's up with that.

Full project on my GitHub https://github.com/ArneSamson/ReactNative-store-app

CodePudding user response:

newItem wont have be updated until the next render. So in this code

let itemdata = JSON.parse(value);
setNewItem(itemdata);
setCartItems((currentItems) => [...currentItems, newItem]);

newItem hasnt yet been updated to itemdata's value. The easiest way around this is to simply use itemdata to update cartItems:

let itemdata = JSON.parse(value);
setNewItem(itemdata);
setCartItems((currentItems) => [...currentItems, itemdata]);
  • Related