简体   繁体   中英

ERROR TypeError: undefined is not an object (evaluating 'state.map')

I am trying to change the state of my 'quantityCounter' but I'm getting an error as the title says. Can anyone help me with changing the state while the value also changes in the screen?

import React from 'react';
import { StyleSheet, View, Text, Button } from 'react-native';
import { useSelector } from 'react-redux';
import { selectCartItems } from '../../../../redux/reducer/cartReducer';
import { selectAllItems } from '../../../../redux/reducer/itemReducer';

const CartList = () => {
  const cartItems = useSelector(selectCartItems);
  const itemData = useSelector(selectAllItems);
  
  const [quantityCounter, setQuantityCounter] = React.useState(cartItems);

  function quantityHandler({id, num}){
    const targetItem = itemData.find((item) => item.id === id);
    let targetCart = quantityCounter.find((cart) => cart.id === id);

    setQuantityCounter((previousState) => 
      previousState.forEach(
        (item) => {
          if(item.id === id){
            Object.keys(item).find(key => {
              if(key === 'quantity'){
                if(num === 1 && targetCart.quantity < targetItem.availableItem){
                  item[key] = targetCart.quantity + 1;
                }
                if(num === 0 && targetCart.quantity > 0) {
                  item[key] = targetCart.quantity - 1;
                }
              }
            })
          }
      }));
  }
  return (
    <>
    {quantityCounter.map((item) => (
      <View style={styles.CartItemsContainer} key={item.id}>
        <Text style={styles.textStyle}>{item.productName}</Text>
        <Text style={styles.textStyle}>{item.productPrice}</Text>
        <View style={styles.quantityContainer}>
          <Button title='-' onPress={() => quantityHandler({id : item.id, num: 0})}/>
          <Text style={styles.quantityContainer__text}>{item.itemQuantity}</Text>
          <Button title='+' onPress={() => quantityHandler({id : item.id, num: 1})}/>
        </View>
      </View>
      ))}
    </>
  )
}

const styles = StyleSheet.create({
  CartItemsContainer:{
    flexDirection: 'row', alignSelf: 'stretch'
  },
  textStyle: {
    flex: 1, alignSelf: 'stretch',
    borderWidth: 1, borderTopColor: 'transparent',
    textAlign: 'center', textAlignVertical: 'center'
  },
  quantityContainer:{
    flex: 1, alignSelf: 'stretch', flexDirection: 'row',
    borderWidth: 1, borderTopColor: 'transparent',
    alignItems: 'baseline', justifyContent: 'center'
  },
  quantityContainer__text:{
    marginHorizontal: 5, marginVertical: 5
  }
});
export default CartList;

Another approach I did was this but the state is only changing, in the screen it doesn't. When the 'quantityHandler' is being pressed, it works as what it is supposed to be but I don't know how to fix or make this work. I tried different way but I can't really show it. Please help.

import React from 'react';
import { StyleSheet, View, Text, Button } from 'react-native';
import { useSelector } from 'react-redux';
import { selectCartItems } from '../../../../redux/reducer/cartReducer';
import { selectAllItems } from '../../../../redux/reducer/itemReducer';

const CartList = () => {
  const cartItems = useSelector(selectCartItems);
  const itemData = useSelector(selectAllItems);
  const [quantityCounter, setQuantityCounter] = React.useState(0);
  let total = 0;
  let id, quantity, name, price;
  let cart_replica = [];
  cartItems.forEach(item => {
    id = item.id;
    name = item.productName;
    price = item.productPrice;
    quantity = item.itemQuantity;
    total += item.totalPrice;
    cart_replica.push({id, name, quantity, price})
  });

  function quantityHandler({id, num}){
    const targetItem = itemData.find((item) => item.id === id);
    let targetCart = cart_replica.find((cart) => cart.id === id);
    cart_replica.map(
      (item) => {
        if(item.id === id){
          return { ...cart_replica, item: { ...item, quantity: item.quantity + 1}};
        }
    });
    console.log(cart_replica[0])

  }
  return (
    <>
    {cart_replica.map((item) => (
      <View style={styles.CartItemsContainer} key={item.id}>
        <Text style={styles.textStyle}>{item.name}</Text>
        <Text style={styles.textStyle}>{item.price}</Text>
        <View style={styles.quantityContainer}>
          <Button title='-' onPress={() => quantityHandler({id : item.id, num: 0})}/>
          <Text style={styles.quantityContainer__text}>{item.quantity}</Text>
          <Button title='+' onPress={() => quantityHandler({id : item.id, num: 1})}/>
        </View>
      </View>
      ))}
    </>
  )
}

const styles = StyleSheet.create({
  CartItemsContainer:{
    flexDirection: 'row', alignSelf: 'stretch'
  },
  textStyle: {
    flex: 1, alignSelf: 'stretch',
    borderWidth: 1, borderTopColor: 'transparent',
    textAlign: 'center', textAlignVertical: 'center'
  },
  quantityContainer:{
    flex: 1, alignSelf: 'stretch', flexDirection: 'row',
    borderWidth: 1, borderTopColor: 'transparent',
    alignItems: 'baseline', justifyContent: 'center'
  },
  quantityContainer__text:{
    marginHorizontal: 5, marginVertical: 5
  }
});
export default CartList;

Can you check this,ive added state manipulation.

Hope it helps:)

https://snack.expo.dev/5vfUoenH3

 import React from 'react'; import { StyleSheet, View, Text, Button, SafeAreaView } from 'react-native'; const App = () => { const [quantityCounter, setQuantityCounter] = React.useState([ { id: 1, name: 'item 1', availableItem: 5, price: 500, quantity: 5, }, { id: 2, name: 'item 2', availableItem: 4, price: 500, quantity: 4, }, { id: 3, name: 'item 3', availableItem: 3, price: 500, quantity: 3, }, ]); const quantityHandler = (id,index,isIncrement) =>{ const newCopy = [...quantityCounter]; if(isIncrement){ newCopy[index].quantity = newCopy[index].quantity +1; }else { newCopy[index].quantity = newCopy[index].quantity -1; } console.log("er",newCopy,index) setQuantityCounter(newCopy) } return ( <SafeAreaView style={styles.safeStyle}> {quantityCounter.map((item,index) => ( <View style={styles.CartItemsContainer} key={item.id}> <Text style={styles.textStyle}>{item.name}</Text> <Text style={styles.textStyle}>{item.price}</Text> <View style={styles.quantityContainer}> <Button title='-' onPress={() => quantityHandler(item.id,index,false)}/> <Text style={styles.quantityContainer__text}>{item.quantity}</Text> <Button title='+' onPress={() => quantityHandler(item.id,index,true)}/> </View> </View> ))} </SafeAreaView> ) } const styles = StyleSheet.create({ safeStyle: { marginTop:'5%' }, CartItemsContainer:{ flexDirection: 'row', alignSelf: 'stretch' }, textStyle: { flex: 1, alignSelf: 'stretch', borderWidth: 1, borderTopColor: 'transparent', textAlign: 'center', textAlignVertical: 'center' }, quantityContainer:{ flex: 1, alignSelf: 'stretch', flexDirection: 'row', borderWidth: 1, borderTopColor: 'transparent', alignItems: 'baseline', justifyContent: 'center' }, quantityContainer__text:{ marginHorizontal: 5, marginVertical: 5 } }); export default App;

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM