React Native/Firebase:平面列表重新呈现和复制密钥问题

React Native/Firebase:平面列表重新呈现和复制密钥问题,firebase,react-native,firebase-realtime-database,react-native-flatlist,react-native-firebase,Firebase,React Native,Firebase Realtime Database,React Native Flatlist,React Native Firebase,我正在使用React Native和Firebase实时数据库。我在FlatList组件中遇到两个问题: 每当列表重新呈现时,我都会收到许多重复的键错误。我不确定为什么会出现此问题,因为我正在将列表中每个项目的键设置为Firebase生成的snap.key值,该值是唯一的,我已在日志中对此进行了验证 列表有时不会重新呈现,即使我在上面或下面滚动。这种行为有时会让我感到厌烦,而我一直无法调试它。我正在使用.on方法从Firebase实时数据库获取我的列表 这是我正在使用的代码: export de

我正在使用React Native和Firebase实时数据库。我在FlatList组件中遇到两个问题:

每当列表重新呈现时,我都会收到许多重复的键错误。我不确定为什么会出现此问题,因为我正在将列表中每个项目的键设置为Firebase生成的snap.key值,该值是唯一的,我已在日志中对此进行了验证

列表有时不会重新呈现,即使我在上面或下面滚动。这种行为有时会让我感到厌烦,而我一直无法调试它。我正在使用.on方法从Firebase实时数据库获取我的列表

这是我正在使用的代码:

export default class FlatListPage extends React.PureComponent {

    constructor(props) {
        super(props); 
        this.state = { 
            data: [],
        }; 
    }

    makeRemoteRequest = () => {
        var items = []; 
        DB.on('value', (snap) => {
            this.getItems(snap, items); 
            items = items.reverse(); 
            this.setState(
                {data: items}
            ); 
            console.log(this.state.data);  //checking key properties are unique 
        }); 

    }

    getItems = (snap, items) => {
        snap.forEach((child) => {
            items.push({
                key: child.key, 
                status: child.val().status, 
                location: child.val().location, 
            });
        });
    }

    componentWillMount(){
        this.makeRemoteRequest(); 
    }

    render() {
        return (
            <View>
                <FlatList
                    data={this.state.data}
                    renderItem={({item}) => <MyListItem item={item} />}
                />
            </View>
        );
    }
}

您正在接收重复的键,因为从firebase接收新值事件时,您没有重置items数组。这意味着您只需一次又一次地添加相同的项目

每次获得值事件时,更新MakeMoteRequest方法以重新创建数组,如下所示:

makeRemoteRequest = () => {
    DB.on('value', (snap) => {
        var items = [];
        this.getItems(snap, items); 
        items = items.reverse(); 
        this.setState(
            {data: items}
        ); 
        console.log(this.state.data);  //checking key properties are unique 
    }); 
}

我不确定第2个问题-可能是上面提到的解决了它的副作用。

而不是每次我建议获取所有元素时都获取整个列表。一次然后使用'child_added'事件和.limitToLast1仅获取新项目并将其添加到数组中。另外,我注意到您正在将项目推送到阵列,然后将其反转。可以使用.unshift方法在数组的开头插入项,这样以后就不必反转数组

谢谢大家!!很好的捕捉,它现在运行得更平稳了,2作为一个副作用正在处理中。如果我想清除.on函数外部的'var items'变量,是否应该在lifecycle方法组件WillUpdate内部执行此操作?我可能需要使用多个.on连接向其中添加更多数据,因此我无法将其放入其中任何一个连接中。