简体   繁体   English

useState 数组未定义,即使它被初始化为空数组

[英]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).我正在使用 Firebase v9 参与 React Native Expo 项目,但由于我的状态变量类别而出现错误(我认为这就是问题所在)。 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.正如它所显示的,我已经收到一条警告,上面写着:'[未处理的承诺拒绝:FirebaseError:使用无效数据调用的函数 setDoc()。 Unsupported field value: undefined (found in field categories in document users/Hk4k6fKrtZZG1BGffFrOTRvuT2h2)]'不支持的字段值:未定义(在文档用户/Hk4k6fKrtZZG1BGffFrOTRvuT2h2 的字段类别中找到)]'

And when i add a category i get the error -> Render error: undefined is not an object(evaluating 'iter[symbol.iterator]')当我添加一个类别时,我得到了错误-> 渲染错误:未定义不是一个对象(评估'iter [symbol.iterator]')

This is the code for my CategoryComponent:这是我的 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.我在我的 useEffect 中 consol.logged 状态变量类别,我不明白为什么当我将它初始化为空数组时它显示“未定义”,所以我希望在 consol.log 中看到一个空数组当平面列表中没有类别时,用于状态变量类别。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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