I am new to React Native, and this is my first project using React Native that build from scratch. I have a warning issue and the feature i want is not working.
Here are some explanation of what i want : I have an array of object that i named it as carts, inside the carts it looks like :
let carts = [
{
merchantId: 1,
items: [
{
productId: 1,
productQty: 1,
},
{
productId: 2,
productQty: 5,
},
],
},
{
merchantId: 2,
items: [
{
productId: 3,
productQty: 2,
},
{
productId: 4,
productQty: 4,
},
],
},
];
And this is my Screen :
import React, { useState, useEffect } from 'react';
import {
StyleSheet,
Text,
View,
Image,
ScrollView,
TouchableOpacity,
} from 'react-native';
import { Button } from 'react-native-paper';
import { theme } from '../../../infrastructure/theme';
import SpacerComponent from '../../../components/SpacerComponent';
import { FontAwesome5 } from '@expo/vector-icons';
import MerchantCardComponent from '../components/MerchantCardComponent';
import { tranformCartArray } from '../../../services/carts/CartTransform';
const CartScreen = ({ navigation }) => {
const [carts, setCarts] = useState([]);
const [isLoading, setIsLoading] = useState(false);
const getCarts = async () => {
setIsLoading(true);
const response = await tranformCartArray();
setCarts(response);
setIsLoading(false);
};
useEffect(() => {
const unsubscribe = navigation.addListener('focus', () => {
getCarts();
});
return unsubscribe;
}, [navigation]);
console.log(carts);
if (carts.length === 0) {
return (
<View style={styles.emptyContainter}>
<Image
style={styles.imageCart}
source={require('../../../assets/images/empty_cart.png')}
/>
<Text style={styles.emptyCartText}>
Keranjangnya masih kosong nih !
</Text>
<SpacerComponent size="xlarge" />
<Button
style={styles.buttonExplore}
mode="contained"
size={20}
onPress={() => navigation.navigate('Merchants')}
>
<FontAwesome5
name="shopping-cart"
size={20}
color={theme.colors.text.inverse}
/>
<Text>{' '}</Text>
<Text style={styles.buttonText}>Eksplor</Text>
</Button>
</View>
);
}
if (isLoading) {
return (
<View style={styles.emptyContainter}>
<ActivityIndicator
color={theme.colors.ui.primary}
size={theme.sizes[3]}
/>
</View>
);
}
return (
<ScrollView style={styles.container}>
{carts.map((merchantAndItems) => {
return (
<TouchableOpacity onPress={() => navigation.navigate('Checkout')}>
<MerchantCardComponent
merchantAndItems={merchantAndItems}
key={merchantAndItems.merchantId}
/>
</TouchableOpacity>
);
})}
</ScrollView>
);
};
export default CartScreen;
const styles = StyleSheet.create({
emptyContainter: {
justifyContent: 'center',
alignItems: 'center',
flex: 1,
backgroundColor: theme.colors.bg.primary,
},
imageCart: {
maxWidth: '90%',
maxHeight: '45%',
aspectRatio: 1,
},
emptyCartText: {
fontSize: 20,
fontFamily: theme.fonts.regular,
},
buttonExplore: {
backgroundColor: theme.colors.ui.primary,
},
buttonText: {
fontSize: 20,
},
container: {
flex: 1,
marginBottom: 10,
},
});
I want to pass after transform carts of array to MerchantCardComponent, the type of the transformation I want is the array (carts) become :
let carts = [
{
merchantId: 1,
merchantName: 'Merchant A',
merchantLogo: 'https://assets.backend.com/merchants/1/logo_url.jpg',
items: [
{
productId: 1,
productName: 'Product One',
productImage: 'https://assets.backend.com/merchants/1/products/1/product_image.jpg',
productPrice: 2000,
productQty: 1,
},
{
productId: 2,
productName: 'Product Two',
productImage: 'https://assets.backend.com/merchants/1/products/2/product_image.jpg',
productPrice: 2000,
productQty: 5,
},
],
},
{
merchantId: 2,
merchantName: 'Merchant B',
merchantLogo: 'https://assets.backend.com/merchants/2/logo_url.jpg',
items: [
{
productId: 3,
productName: 'Product Three',
productImage: 'https://assets.backend.com/merchants/2/products/3/product_image.jpg',
productPrice: 2000,
productQty: 2,
},
{
productId: 4,
productName: 'Product Four',
productImage: 'https://assets.backend.com/merchants/4/products/4/product_image.jpg',
productPrice: 2000,
productQty: 4,
},
],
},
];
So that i can easily just print out the text, without fetch to backend again in the screen. I have make an seperate file for the transform the cart function, here is the code :
import React, { useContext, useState } from 'react';
import CartsContext from './CartsContext';
import {
doRequestMerchantDetail,
doRequestProductDetail,
} from '../merchants/MerchantsService';
export const tranformCartArray = async () => {
const [transformCart, setTransformCart] = useState([]);
const [afterTransform, setAfterTransform] = useState(null);
const [items, setItems] = useState([]);
const { carts } = useContext(CartsContext);
for (let i = 0; i < carts.length; i++) {
let [errMerchant, merchant] = await doRequestMerchantDetail(
carts[i].merchantId,
);
for (let j = 0; j < cart[i].items.length; j++) {
let [errProduct, product] = await doRequestProductDetail(
carts[i].items[j].productId,
);
if (product) {
setItems(
...items,
...[
{
productName: product.product_name,
productQty: carts[i].items[j].productQty,
productPrice: product.product_price,
productId: carts[i].items[j].productId,
productImage: product.product_image_url,
},
],
);
} else {
setItems(
...items,
...[
{
productName: 'Error',
productQty: carts[i].items[j].productQty,
productPrice: 'Error',
productId: carts[i].items[j].productId,
productImage:
'https://cdn.pixabay.com/photo/2021/07/21/12/49/error-6482984_960_720.png',
},
],
);
}
}
if (merchant) {
setAfterTransform({
merchantName: merchant.name,
merchantLogo: merchant.merchant_logo_url,
merchantId: carts[i].merchantId,
items,
});
} else {
setAfterTransform({
merchantName: 'Error',
merchantLogo: 'Error',
merchantId: carts[i].merchantId,
items,
});
}
setTransformCart(...transformCart, ...[afterTransform]);
}
return transformCart;
};
Until now i'm still confuse what make the warning show out, and the not working i was mention in the first sentence is the it return an empty array after the transform. Here is the screenshoot of console
