React Native/Firebase:FlatList 重新渲染和重复键的问题
React Native/Firebase: Issue with FlatList Re-Rendering & Duplicate Keys
我正在使用 React Native 和 Firebase 实时数据库。 FlatList
组件有两个问题:
每当列表重新呈现时,我都会收到很多 "duplicate key" 错误。我不确定为什么会遇到这个问题,因为我将列表中每个项目的键设置为 Firebase 生成的 snap.key
值,这是唯一的(我已经在日志中验证了这一点)。
列表有时不会重新呈现,即使我向上或向下滚动它也是如此。这种 "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 方法在数组的开头插入项目,这样您以后就不必将其反转。
我正在使用 React Native 和 Firebase 实时数据库。 FlatList
组件有两个问题:
每当列表重新呈现时,我都会收到很多 "duplicate key" 错误。我不确定为什么会遇到这个问题,因为我将列表中每个项目的键设置为 Firebase 生成的
snap.key
值,这是唯一的(我已经在日志中验证了这一点)。列表有时不会重新呈现,即使我向上或向下滚动它也是如此。这种 "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 方法在数组的开头插入项目,这样您以后就不必将其反转。