简体   繁体   中英

useState array is undefined even though it is initialized as empty array

I'm working in a React Native Expo project with Firebase v9 and I'm getting an error because of my state variabel categories(I think that's the issue). This component allows the user to add categories to a flatlist, which is seen here:

As it shows i'm already getting an warning which says: '[Unhandled promise rejection: FirebaseError: Function setDoc() called with invalid data. Unsupported field value: undefined (found in field categories in document users/Hk4k6fKrtZZG1BGffFrOTRvuT2h2)]'

And when i add a category i get the error -> Render error: undefined is not an object(evaluating 'iter[symbol.iterator]')

This is the code for my CategoryComponent:

import { StyleSheet, View, FlatList, Alert, Animated} from 'react-native'
import React, { useState, useEffect} from 'react'
import { db, } from '../../firebase/firebase'
import { doc, setDoc, onSnapshot} from 'firebase/firestore';
import firebase from 'firebase/compat/app';
import { Button, Divider, Subheading, Text, Modal, Portal, TextInput } from 'react-native-paper';
import Swipeable from 'react-native-gesture-handler/Swipeable'
import { TouchableOpacity } from 'react-native-gesture-handler';
import { useNavigation } from '@react-navigation/native';


export default function CategoryComponent() {
  const containerStyle = {backgroundColor: 'white', padding: 100, margin: 10};
  const [textInput, setTextInput] = useState('');
  const [visible, setVisible] = useState(false);
  const [categories, setCategories] = useState([])
  const navigation = useNavigation();
  const [dataFetch, setDataFetch] = useState(false);


  useEffect(
    () => 
      onSnapshot(doc(db, "users", `${firebase.auth().currentUser.uid}`), (doc) => {
        setCategories(doc.data().categories)
        setDataFetch(true)
      }
      ),
      console.log(categories),
    []
  );


  useEffect(() => {
    addToFirebase();
  }, [categories])


  const showModal = () => {
    setVisible(true);
  }
  

  const hideModal = () => {
    setVisible(false);
  }


  const categoryNavigate = (item) => {
    navigation.navigate("Your Organizer tasks", {item});
  }


  const addCategory = (textInput) => {
    setCategories((prevState) => {
      return [
        {name: textInput, id: Math.floor(Math.random() * 10000) + 1 },
        ...prevState
      ];
    })

    hideModal();
  }


  const addToFirebase = async() => {
    if(dataFetch) {
      await setDoc(doc(db, "users", `${firebase.auth().currentUser.uid}`), {
        categories: categories
      }, {merge: true});
    }
  };

  
  const deleteItem = (item) => {
    setCategories((prevState) => {
      return prevState.filter(category => category.id != item.id)
    })        
  }


  const DataComponent = (item) => {
    const rightSwipe = (progress, dragX) => {
      const scale = dragX.interpolate({
        inputRange: [-100, 0],
        outputRange: [1, 0],
        extrapolate: 'clamp'
      });

      return(
        <TouchableOpacity activeOpacity={0.8} onPress={() => deleteItem(item)}>
          <View>
            <Animated.Text style={[styles.deleteItem, {transform: [{scale}]}]}>Delete</Animated.Text>
          </View>
        </TouchableOpacity>
      )
    }

    return (
    <TouchableOpacity onPress={() => categoryNavigate(item)}>
      <Swipeable renderRightActions={rightSwipe}>
        <View>
          <Text>{item.name}</Text>
        </View>
      </Swipeable>
    </TouchableOpacity>
    )
  }


  return (
    <View>
      <Subheading>Your categories</Subheading>
        <View>
          <FlatList
          style={styles.flatList}
          keyExtractor={(item) => item.id}
          data={categories}
          renderItem={ ({item}) => (
            <DataComponent {...item}/>
            )}
            />
        </View>

      <View>
        <Button mode="contained" uppercase={false} onPress={showModal}>
          Add a category
        </Button>
      </View>
      <Portal>
        <Modal visible={visible} onDismiss={hideModal} contentContainerStyle={containerStyle}>
          <Text>Name your category: </Text>
          <TextInput placeholder="Enter category name" value={textInput} onChangeText={val => setTextInput(val)}/>
          <Button mode="contained" uppercase={false} onPress={() => addCategory(textInput)}>
            Add
          </Button>
        </Modal>
      </Portal>
    </View>
  )
}

I have consol.logged the state variable categories in my useEffect and i don't understand why it shows ''undefined'' when I have initialized it as an empty array, so i would expect to see a empty array in the consol.log for the state variable categories when there is no categories in the flatlist.

如果您清楚地看到对象中没有这样的类别类型键值,那么当您执行 setCategories(doc.data().categories) 时,它会将类别值设置为 undefined 。您无法在字段值的位置合并或添加 Doc未定义。

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