【发布时间】:2021-12-29 20:04:12
【问题描述】:
我有一个简单的应用程序,用户可以在其中从 addAnimal.js 屏幕将动物添加到 Firebase 数据库,然后我使用 UseEffect 在主屏幕中捕捉到它。我正在使用 useState 来加载我的数据,然后使用平面列表呈现它。
每当我添加新动物时,也会添加前一个动物。例如,我展示了 1 只狗,然后我用 FAB 添加了一只新猫,所以应该有 2 只,但是当我返回时,我有 2 只狗和 1 只猫。我试图实现一个 if 语句来跳过重复但没有运气。我怎样才能做到这一点?
我也不确定我是否在 UseEffect 中正确使用了登录系统。
import React, { useState} from 'react';
import { Button, Text, View, StyleSheet, Image, Animated, Dimensions } from 'react-native';
import { FlatList, TouchableOpacity } from 'react-native-gesture-handler';
import Icon from 'react-native-vector-icons/FontAwesome';
import { onValue } from 'firebase/database';
import {signInAnonymously} from 'firebase/auth';
import { db, ref,set, auth } from '../shared/setup';
import Card from '../shared/card';
import {kutya ,macska,nyul} from '../assets';
const AllatokScreen = ({navigation, route}) => {
const [allatok, setAllat] = useState([]);
const anonymous_login =() => {
signInAnonymously(auth)
.then((result) => {
console.log(result)
})
.catch((error) => {
const errorCode = error.code;
const errorMessage = error.message;
// ...
});
}
const loadAnimails = () => {
//Make query from database
var userRoot = ref(db, "users/"+auth.currentUser.uid+"/allatok");
let updatedValue = {};
onValue(userRoot, (snapshot) => {
var data = snapshot.val();
var key;
for (var line in data) {
key = line;
updatedValue = {"allatID":line, "allatFaj": data[key]['AllatFaj'],allatNev: data[key]['AllatNev']};
if (!allatok.includes(updatedValue)) {
//Not sure what to use here, I try to skip the duplicates
//setAllat(allatok.concat(updatedValue))
//setAllat(prevArray => [...prevArray, updatedValue])
}
}
});
}
useEffect(() => {
onAuthStateChanged(auth, user => {
if (user != null) {
Animated.timing( animation, { toValue:2, duration:300, useNativeDriver:false}).start();
//Found User
console.log('We are authenticated now!');
console.log("User ID: "+user.uid)
//Load animals
loadAnimails();
}
});
},
[])
return (
<View style={[styles.container,styles.center]}>
<View style={styles.center}>
{(() => {
if (Object.keys(allatok).length === 0){
return (
<Text>There are no animals here yet, use the button below to add some</Text>
)
} else {
return (
<FlatList data = {allatok} renderItem={({item}) =>(
<TouchableOpacity
style={styles.TouchableOpacity}
onPress={() => {navigation.navigate('AllatokScreen_to_InsideAllat', item.allatID)}}
>
<Card>
{item.allatFaj == 'kutya'? <Image style={styles.image} source={kutya}/>: null }
{item.allatFaj == 'macska'? <Image style={styles.image} source={macska}/>: null }
{item.allatFaj == 'nyul'? <Image style={styles.image} source={nyul}/>: null }
<Text>
{item.allatNev}
</Text>
</Card>
</TouchableOpacity>
)} />
)
}
})()}
<TouchableOpacity
style={styles.floatingActionButton}
onPress={() => {navigation.navigate('AllatokScreen_to_AddAllat')}}
>
<Icon name="plus" size={30} color='#ffffff'/>
</TouchableOpacity>
</View>
</View>
);
}
export default AllatokScreen;
这是我的 addAnimal 屏幕:
const AddAllat = ({navigation, route}) => {
//console.log(route);
const [AllatNev, setAllatNev] = React.useState('');
const [AllatFajta, setAllatFajta] = React.useState('');
const [AllatSzin, setAllatSzin] = React.useState('');
const [AllatNem, setAllatNem] = React.useState('');
//------------------DateTimePicker------------------
const [show, setShow] = useState(false);
const [date, setDate] = useState(new Date());
const [dateText, setDateText] = useState('Dátum kiválasztása')
const showPicker = () => {
setShow(true);
};
const onChange = (event, selectedDate) => {
const currentDate = selectedDate || date;
setShow(Platform.OS === 'ios');
setDate(selectedDate);
let tempDate = new Date(currentDate);
let fDate = tempDate.getFullYear() + '-' + tempDate.getMonth() + '-' + tempDate.getDate();
setDateText(fDate)
};
//------------------DateTimePicker------------------
//------------------DropDownBox variables------------------
const [openNem, setOpenNem] = useState(false);
const [valueNem, setValueNem] = useState(null);
const [itemsNem, setItemsNem] = useState([
{label: 'Hím', value: 'him'},
{label: 'Nőstény', value: 'nosteny'}
]);
const [openFaj, setOpenFaj] = useState(false);
const [valueFaj, setValueFaj] = useState(null);
const [itemsFaj, setItemsFaj] = useState([
{label: 'Kutya', value: 'kutya'},
{label: 'Macska', value: 'macska'},
{label: 'Nyúl', value: 'nyul'},
{label: 'Gekkó', value: 'gekko'},
{label: 'Hörcsög', value: 'horcsog'}
]);
//------------------DropDownBox variables------------------
const onClick_addUjAllat = () => {
var allatid = "allatid" + Math.random().toString(16).slice(2)
//Sending data to firebase db
const reference = ref(db, "users/"+auth.currentUser.uid +"/allatok/"+allatid);
set(reference, {
'AllatNev': AllatNev,
'AllatFaj': valueFaj,
'AllatFajta': AllatFajta,
'AllatSzin': AllatSzin,
'AllatNem': valueNem,
'AllatSzul': dateText
});
//Notify then Exit from here
alert('New animal added!')
navigation.goBack();
}
return (
<View style={styles.container}>
<Text>USER ID: {auth.currentUser.uid}</Text>
<TextInput
placeholder="Állat neve"
style={styles.textBox}
value={AllatNev}
onChangeText={(text) => setAllatNev(text)}
/>
<DropDownPicker
open={openFaj}
value={valueFaj}
items={itemsFaj}
setOpen={setOpenFaj}
setValue={setValueFaj}
setItems={setItemsFaj}
placeholder="Faj kiválasztása"
dropDownDirection="BOTTOM"
/>
<TextInput
placeholder="Fajtája"
style={styles.textBox}
value={AllatFajta}
onChangeText={(text) => setAllatFajta(text)}
/>
<TextInput
placeholder="Színe"
style={styles.textBox}
value={AllatSzin}
onChangeText={(text) => setAllatSzin(text)}
/>
<Text>Születési dátum: </Text>
<TouchableOpacity style={styles.textBox} onPress={showPicker}>
<Text style={styles.pickedDate}>{dateText}</Text>
</TouchableOpacity>
{show && (
<DateTimePicker
value={date}
mode={'date'}
display={Platform.OS === 'ios' ? 'spinner' : 'default'}
onChange={onChange}
style={styles.datePicker}
/>
)}
<DropDownPicker
open={openNem}
value={valueNem}
items={itemsNem}
setOpen={setOpenNem}
setValue={setValueNem}
setItems={setItemsNem}
placeholder="Nem kiválasztása"
dropDownDirection="TOP"
containerStyle={{width: 250}}
itemStyle={{alignItems: 'center'}}
activeLabelStyle={{color: 'red'}}
/>
<TouchableOpacity stlye={styles.buttonStyle} onPress={onClick_addUjAllat}>
<Text style={{color:'black'}}>Hozzáadás</Text>
</TouchableOpacity>
</View>
);
}
export default AddAllat;
【问题讨论】:
-
项目是否可以更新,或者只是添加?如果它们无法更新,只需在更新前检查您的原始数组以查看您是否有匹配的 ID。如果可以更新它们,则需要检查每个对象是否相等。
-
副本是添加到您的数据库中还是只是在您应用的渲染中?
-
@Abe 只是在应用程序渲染中,每当我返回主页时,UseEffect 会触发我的动物加载功能,它不会跳过重复项
-
@jnpdx 我相信我可以做到这两点,但我不知道如何......你能提供一些例子吗?这不起作用,为什么“如果(!allatok.includes(updatedValue))”。我的逻辑是当我添加动物时,我返回到函数运行的主屏幕(UseEffect-->loadAnimals()),在那里我检查数组中的对象是否在那里,如果它在那里我跳过,但是它不会跳过它...
标签: javascript android reactjs react-native react-hooks