React Native 和 Firebase 实时数据库

3

我在使用React Native和Firebase实时数据库时遇到了两个问题。

  • 当我使用文本输入向列表中添加内容时,除了我刚刚添加的项目之外,所有列表项都会复制一次。只有刷新应用程序屏幕后才能解决这个问题。

  • 当我从Firebase控制台或其他客户端删除某些内容时,列表不会实时更新。

  import React, {useState, Component} from 'react';
  import {
    Text,
    View,
    Switch,
    StyleSheet,
    FlatList,
    TextInput,
    Button,
    TouchableOpacity,
    SafeAreaView,
    VirtualizedList,
  } from 'react-native';

  import database from '@react-native-firebase/database';

  class MenuBreakFastScreen extends React.Component {
    state = {newItem: ''};
    state = {itens: []};

    componentDidMount() {
      let dbRef = database().ref('/cafe/itens/');
      this.listenerFirebase(dbRef);
    }

    listenerFirebase(dbRef) { 
      dbRef.on('value', dataSnapshot => {
        const newItens = JSON.parse(JSON.stringify(this.state.itens));
        dataSnapshot.forEach(child => {
          newItens.push({
            name: child.val().name,
            key: child.key,
          });
          this.setState({itens:newItens});
        });
      });
    }

    addItem() {
      if (this.state.newItem === '') {
        return;
      }
      database().ref('/cafe/itens/').push({
        name: this.state.newItem,
      });
      this.setState({
        newItem: '',
      });
    }

    render() {
      const {itens} = this.state;
      const {newItem} = this.state;
      const renderItem = ( {item}) => {
        return(
          <ItemAsset title={item.name}/>
        );
      }
      return (
        <SafeAreaView
          style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
          <FlatList 
          data={itens}
          renderItem={renderItem}
          keyExtractor={item => item.key}
          />
          <SafeAreaView style={{flexDirection: 'row'}}>
            <TextInput
              style={styles.input}
              onChangeText={text =>
                this.setState({
                  newItem: text,
                })
              }
              value={newItem}
            />
            <TouchableOpacity style={styles.Botao} onPress={() => this.addItem()}>
              <Text style={styles.BotaoTexto}>+</Text>
            </TouchableOpacity>
          </SafeAreaView>
        </SafeAreaView>
      );
    }
  }

  const styles = StyleSheet.create({
    texto: {
      fontSize: 35,
    },
    input: {
      color: '#000',
      fontSize: 22,
      borderWidth: 1,
      flex: 8,
      margin: 10,
    },
    BotaoTexto: {
      color: '#fff',
      fontSize: 22,
    },
    Botao: {
      backgroundColor: '#000',
      marginTop: 10,
      padding: 10,
      flex: 1,
      alignItems: 'center',
      margin: 10,
    },
    ListaContainer: {
      flexDirection: 'row',
      backgroundColor: '#000',
      flex: 1,
    },
    item: {
      backgroundColor: '#000',
      padding: 20,
      marginVertical: 8,
      marginHorizontal: 16,
      flexDirection: 'row',
    },
    title: {
      color: '#ffff',
      fontSize: 32,
    }, 
  });

  const ItemAsset = ( {title} ) => {
    return(
      <View style={styles.item}>
        <Text style={styles.title}>{title}</Text>
      </View>
    );
  }
  export default MenuBreakFastScreen;


你定义了两次状态:state = { newItem: '' }; 然后 state = { itens: [] }; - Michael Rovinsky
1个回答

4

当你监听实时数据库的实时更改时,它会在任何数据更改时发送所有项目的快照。这是因为你监听整个列表,而不仅仅是单个项目。因此,你不需要从状态中获取当前列表。你只需要用检索到的数据设置状态。

   listenerFirebase(dbRef) { 
      dbRef.on('value', dataSnapshot => {
        const newItens = [];         // This should be initially empty array. That's all.
        dataSnapshot.forEach(child => {
          newItens.push({
            name: child.val().name,
            key: child.key,
          });
        });
        this.setState({itens:newItens});
      });
    }

在更正此部分后,您在删除数据时遇到的错误也将得到解决。


1
非常感谢,现在一切都正常工作。 - Reis
@Gabriellcreiss 注意关于 setState 调用位置的新更改。 - samthecodingman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接