react native - why is my console.log returning [] but items get rendered on screen? - react-native

I am trying to access the object obtained from my API get request but I keep getting Array[] returned in the console.log while the items get rendered on the screen.
Can someone spot where I went wrong?
const [posts, setPosts] = useState([]);
const [error, setError] = useState(false);
const [loading, setLoading] = useState(false);
const loadPosts = async () => {
setLoading(true);
const response = await messagesApi.getMessages();
setLoading(false);
if (refreshing) setRefreshing(false);
if (!response.ok) return setError(true);
setError(false);
setPosts(response.data);
};
useEffect(() => {
const newsocket = io.connect("http://ip:port");
loadPosts();
console.log(posts); // not working
newsocket.on("connect", (msg) => {
setSocket(newsocket);
});
return () => newsocket.close();
}, []);
return (
<FlatList
data={posts}
keyExtractor={(post) => post.id.toString()}
renderItem={({ item, index }) => (
<MessagesList
title={item.title}
onPress={() =>
navigation.navigate(routes.CHAT, { message: item, index, updateView })
}
/>
)}
/>
);

ISSUE
console.log executes before getting an API response.
SOLUTION
console.log would work when you add posts in dependency like
useEffect(() => {
console.log(posts);
}, [posts]); // added posts here

Related

React Native - context + firebase

I need to pass one value from firestore to application context. I don't know where am I going wrong? Has anyone had a similar problem? I searched the website but couldn't find anything similar.
export const AuthProvider = ({children}) => {
const [user, setUser] = useState();
const [contextWeight, setContextWeight] = useState();
}
return (
<AuthContext.Provider
value={{
user,
setUser,
contextWeight,
setContextWeight,
unit: async () => {
await firestore()
.collection('users')
.doc(auth().currentUser.uid)
.collection('products')
.doc('product')
.get()
.then(( documentSnapshot ) => {
if( documentSnapshot.exists ) {
setContextWeight(documentSnapshot.data().weightUnit);
}
}).catch(error => {
console.log(error);
})
}}>
{children}
</AuthContext.Provider>
);

React Native with API, Error: undefined is not an object

I'M trying to use Weather API with React Native, but the error below occurred.
It seems that a problem is that const is used before getAdressData done.
How can I use const in this case and fix this error?
Error
undefined is not an object (evaluating 'whether.sys.sunrise')
Codes
〜〜〜〜〜〜〜〜〜〜
export const AddressScreen = () => {
const [address, setAddress] = useState('');
const baseURL = `${APIKey}`
const getAddressData = () => {
axios.get(baseURL)
.then((response) => {setAddress(response.data)})
.catch(error => console.log(error))
};
const sunrise = new Date(weather.sys.sunrise * 1000); //Error
const sunriseTime = sunrise.toLocaleTimeString();
return (
<KeyboardAvoidingView>
〜〜〜〜〜〜〜〜
<View>
<Text>
Sunrise: {(sunriseTime)}
</Text>
</View>
</KeyboardAvoidingView>
);
The JavaScript compiler error is clear with the error. you are trying to access weather.sys.sunrise object property but not defined/initialized.
It seems that you are trying to fetch weather information of a specific location. If that is the intention of your code.
Refactor code as below :
export const AddressScreen = () => {
const [address, setAddress] = useState(null);
const baseURL = `${APIKey}`;
console.log("Fetched weather data:",address)
const getAddressData = () => {
axios
.get(baseURL)
.then((response) => {
console.log("Server response:",response)
setAddress(response.data);
})
.catch((error) => console.log(error));
};
useEffect(() => {
getAddressData();
}, []);
// Don't access weather data until fetched and assigned to state value.
if (!address?.sys) return null;
const sunrise = new Date(address.sys.sunrise * 1000);
const sunriseTime = sunrise.toLocaleTimeString();
return (
<KeyboardAvoidingView>
<View>
<Text>Sunrise: {sunriseTime}</Text>
</View>
</KeyboardAvoidingView>
);
};

Promise Rejection with axios. try to make HTTP instead of HTTPs [ duplicate ]

I pull data from the API and write it to the application with usestate() when the app runs there are no problems, but after 10-30 seconds I get this error.
Here is my code.
const App = () => {
const [datas, setDatas] = useState([])
const res = async () => {
const response = await axios.get("http://hasanadiguzel.com.tr/api/kurgetir")
setDatas(response.data.TCMB_AnlikKurBilgileri)
}
res()
return (
<SafeAreaView style={style.container}>
<View>
{datas.map((item) => {
return (
<KurCard
title={item.Isim}
alis={item.BanknoteBuying}
satis={item.BanknoteSelling}
/>
)
})}
</View>
</SafeAreaView>
)
}
How can I fix this ?
Hi #n00b,
The problem is with your URL Protocol.
const App = () => {
const [datas, setDatas] = useState([]);
const res = async () => {
try {
const url = "https://hasanadiguzel.com.tr/api/kurgetir";
const response = await axios.get(url);
const data = await response.data;
console.log(data.TCMB_AnlikKurBilgileri); // check you console.
setDatas(response.data.TCMB_AnlikKurBilgileri);
} catch (error) {
console.log(error);
}
};
useEffect(() => {
res();
}, []);
And also check this out:- Codesandbox.
And please read this Stack Overflow discussion for better understanding:- stackoverflow

Flatlist is very slow in using big data in react native

i have a big data list of products thats paginate, in every page it load 10 item, but when i add new items to itemlist,flatlist gets very slow,As the number of pages increases, so does the loading time of new products,The function of the choose button is also slowed down.
How to speed up loading I tried all the best methods but it still did not work. Did not React Native really solve this problem?
export default function Products(props) {
const toast = useToast();
const [isLoading, setSetIsLoading] = useState(true);
const [items, setItems] = useState([]);
const [fetchStatus, setFetchStatus] = useState(false);
const [page, setPage] = useState(1);
const [sending, setSending] = useState(false);
async function getProducts() {
let token = await AsyncStorage.getItem('#token');
let data = {
token: token,
page: page,
};
await get_products(data)
.then(res => {
setItems([...items, ...res.data.data.docs]);
setPage(res.data.data.nextPage);
})
.catch(err => {
console.log(err);
});
}
async function getNextPage() {
let token = await AsyncStorage.getItem('#token');
let data = {
token: token,
page: page,
};
await get_products(data)
.then(res => {
setItems([...items, ...res.data.data.docs]);
setPage(res.data.data.nextPage);
})
.catch(err => {
console.log(err);
});
}
async function selectProduct(id) {
setSending(true);
console.log({id});
let token = await AsyncStorage.getItem('#token');
let data = {
product_id: id
};
await select_products(data,token).then(res => {
toast.show({
description:res.data.message
})
setSending(false);
}).catch(rej => {
console.log({rej})
toast.show({
description:rej?.response?.data.message,
})
setSending(false);
})
}
useFocusEffect(
React.useCallback(() => {
getProducts();
return () => {
setItems([]);
setPage();
};
}, []),
);
renderItem =({item}) => (
<Card
selectProduct={id => selectProduct(id)}
sending={sending}
obj={item}
/>
)
return (
<View mb={20}>
<FlatList
data={items}
extraData={items}
removeClippedSubviews={true}
renderItem={renderItem}
keyExtractor={(item) => `${item._id}-item`}
onEndReached={getNextPage}
maxToRenderPerBatch="13"
ListFooterComponent={() => {
return <ActivityIndicator color="orange" size="large" />;
}}></FlatList>
</View>
);
}
Did you use **map method **?
It can help you for more easily loading data

Flatlist inside tab navigator is scrolling to top on state change in react native

Here you can see the gif
Here is my whole Navigator functional component. I'm trying to implement two tabs using Tab Navigator. One to display the cryptos and the other to display the forex data.
The problem is, when I try to load more data on reaching the flatlist's end, the flatlist is scrolling to the top since I'm making a state change [page+1].
const Navigator = () => {
const Tab = createMaterialTopTabNavigator();
const renderItems = ({ item }) => (
<Text>{item.name}<Text>
);
const fetchMarketData = async () => {
console.log("Fetching");
const marketData = await getCryptoMarketData({ page });
if (marketData != "Network Error") {
const ids = data.map((item) => item.id);
let newData = marketData.filter((item) => !ids.includes(item.id));
setData([...data, ...newData]);
setFetching(false);
} else {
setFetching(false);
Alert.alert(marketData, "Sorry for the inconvenience");
}
};
useEffect(() => {
setFetching(true);
const data = async () => {
await fetchMarketData();
};
}, [page]);
const handleLoadMore = async () => {
setFetching(true);
setPage((page) => page + 1);
};
const ScreenA = () => (
<FlatList
data={data}
style={{ backgroundColor: "white" }}
keyExtractor={(item) => item.id}
renderItem={renderItems}
scrollEventThrottle={16}
onEndReached={handleLoadMore}
onEndReachedThreshold={0}
/>
);
return (
<Tab.Navigator
screenOptions={({ route }) => screenOptions(route)}
keyboardDismissMode="auto"
>
<Tab.Screen name="Crypto" component={ScreenA} />
<Tab.Screen name="Forex" component={ScreenC} />
</Tab.Navigator>
);
};
export default Navigator;
OnEndReached is firing the handleLoadMore function and after the state change on data, the Flatlist is scrolling to the top.
1st reason
you have typo in "fetchMarketData", how exactly u get "newData" because i cant see it anywhere, maybe it should be "marketData" if not then u adding SAME old data PLUS undefined[...data, ...undefined]
2nd reason
reason why is that u call setPage(page + 1) and then "fetchMarketData" this is bad why ? because setState is async and it can be changed instant or after 5 secound, so u dont know when its changed and this is why we have hooks, you can use "useEffect" to handle this
change your "handleLoadMore" for example like this
const handleLoadMore = () => {
setPage(page + 1);
};
add useEffect hook that runs when "page" state changes
React.useEffect(() => {
(async() => {
setFetching(true)
const marketData = await getCryptoMarketData({ page });
if (marketData != "Network Error") {
setData([...data, ...marketData]);
} else {
Alert.alert(marketData, "Sorry for the inconvenience");
}
setFetching(false)
})()
}, [page])