React Native/Firebase:FlatList 重新渲染和重复键的问题

React Native/Firebase: Issue with FlatList Re-Rendering & Duplicate Keys

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

  1. 每当列表重新呈现时,我都会收到很多 "duplicate key" 错误。我不确定为什么会遇到这个问题,因为我将列表中每个项目的键设置为 Firebase 生成的 snap.key 值,这是唯一的(我已经在日志中验证了这一点)。

  2. 列表有时不会重新呈现,即使我向上或向下滚动它也是如此。这种 "sometimes" 行为让我很不爽,我无法调试它。我正在使用“.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 的新 value 事件时没有重置 items 数组。这意味着您只是一遍又一遍地重新添加相同的项目。

更新您的 makeRemoteRequest 方法以在每次收到 value 事件时重新创建数组,如下所示:

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 个问题 - 可能是上述修复了它作为副作用。

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