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]);