我的代码可以工作并从Cloud Firestore检索数据(“ Component Did Mount” +“ retrieveData”)并设置状态,但是当React Native Flat List组件检索其他数据(retrieveMore)时,我需要传递先前的状态并追加文档数据到this.state.documentData。
该数据库包含20个文档,其ID从1到19。第一个查询检索9个文档,第二个查询检索9个文档,最后一个查询将返回1个文档(共19个)
当列表滚动到底部时,flatList将从Cloud Firestore获取其他文档,并将上一个查询中的最后一个可见文档作为起点。我可以将文件数据+ lastVisible获取到resolveMore函数,但是我无法弄清楚为什么使用.startAfter(this.state.lastVisible)查询将无法工作
我收到以下错误(来自retrieveMore函数): 函数Query.startAfter()需要一个有效的第一个参数,但未定义。
有效的方法:
错误所在的位置:
这是我的代码:
// Imports: Dependencies
import React, { Component } from "react";
import { ActivityIndicator, Dimensions, FlatList, SafeAreaView, StyleSheet, Text, View } from 'react-native';
import { usersRef } from '../App';
// Imports: Components
import ItemSelector from '../components/ItemSelector';
import Title from '../components/Title';
// Screen Dimensions
const { height, width } = Dimensions.get('window');
// Screen: InfiniteScroll
export default class InfiniteScroll extends React.Component {
constructor(props) {
super(props);
this.state = {
documentData: [],
lastVisible: null,
loading: false,
refreshing: false,
};
}
// Component Did Mount
componentDidMount = () => {
try {
// Cloud Firestore: Initial Query (Infinite Scroll)
this.retrieveData()
}
catch (error) {
console.log(error);
}
}
// Retrieve Data
retrieveData = async () => {
try {
// Set State: Loading
// this.setState({ loading: true });
this.setState((prevState) => {
return ({...prevState, loading: true})
})
console.log('Retrieving Data');
// Cloud Firestore: Query
let initialQuery = await usersRef
.where('id', '<=', 20)
.orderBy('id')
.limit(9)
// Cloud Firestore: Query Snapshot
let documentSnapshots = await initialQuery.get();
// Cloud Firestore: Document Data
let documentData = documentSnapshots.docs.map(document => document.data());
console.log('Document Data (Retrieve Data)');
console.log(documentData);
// Cloud Firestore: Last Visible Document (To Start From For Proceeding Queries)
let lastVisible = documentData[documentData.length - 1];
console.log('Last Visible (Retrieve Data)');
console.log(lastVisible);
// Set State
this.setState({
documentData: documentData,
lastVisible: lastVisible,
loading: false,
});
}
catch (error) {
console.log(error);
}
}
// Retrieve More
retrieveMore = async () => {
try {
// Set State: Refreshing
console.log('Retrieving additional Data');
this.setState(prevState => ({
documentData: prevState.documentData,
lastVisible: prevState.lastVisible,
refreshing: true,
}));
console.log('Previous State: Document Data');
console.log(this.state.documentData);
console.log('Previous State: Last Visible (Works Up Until Here. lastVisible works, but it doesn\'t work as the starting point for the additionalQuery)');
console.log(this.state.lastVisible);
// Cloud Firestore: Query (Additional Query)
let additionalQuery = await usersRef
.where('id', '<=', 20)
.orderBy('id')
.startAfter(this.state.lastVisible)
.limit(9)
// Cloud Firestore: Query Snapshot
let documentSnapshots = await additionalQuery.get();
// Cloud Firestore: Document Data
let documentData = documentSnapshots.docs.map(document => document.data());
console.log('Document Data (Retrieve More) (Post 2nd Query)');
console.log(documentData);
// Cloud Firestore: Last Visible Document (To Start From For Proceeding Queries)
let lastVisible = documentData[documentData.length - 1];
console.log('Last Visible (Retrieve More) (Post 2nd Query)');
console.log(lastVisible);
// Set State (Signature)
this.setState(prevState => ({
documentData: [...prevState.documentData, documentData],
lastVisible: lastVisible,
refreshing: false,
}));
}
catch (error) {
console.log(error);
}
}
// Render Header
renderHeader = () => {
try {
return (
<Title title="Items" />
)
}
catch (error) {
console.log(error);
}
};
// Render Footer
renderFooter = () => {
try {
// Check If Loading
// if (this.state.loading || this.state.refreshing) {
if (this.state.loading) {
return (
<View style={styles.activityIndicator}>
<ActivityIndicator />
</View>
)
}
else {
return null;
}
}
catch (error) {
console.log(error);
}
};
// Select Item
selectItem = (item) => {
try {
console.log(`Selected: ${item.first_name}`)
}
catch(error) {
console.log(error);
}
}
render() {
return (
<SafeAreaView style={styles.container}>
<FlatList
// Data takes in an array
data={this.state.documentData}
// Render Items
renderItem={({ item }) => (
<ItemSelector
item={item.first_name}
// onPress={() => {this.selectItem(item)}}
/>
)}
// Element Key
keyExtractor={(item, index) => String(index)}
// Header (Title)
ListHeaderComponent={this.renderHeader}
// Footer (Activity Indicator)
ListFooterComponent={this.renderFooter}
// On End Reached takes in a function
onEndReached={this.retrieveMore}
// How Close To The End Of List Until Next Data Request Is Made
onEndReachedThreshold={0}
// Refreshing (Set To True When End Reached)
refreshing={this.state.refreshing}
/>
</SafeAreaView>
)
}
}
// Styles
const styles = StyleSheet.create({
container: {
height: height,
width: width,
},
text: {
fontFamily: 'System',
fontSize: 16,
fontWeight: '400',
color: '#222222',
},
});
console.log:retrieveData
Retrieving Data
Document Data (Retrieve Data)
Array [
Object {
"first_name": "Kristin",
"id": 1,
"last_name": "Smith",
},
Object {
"first_name": "Olivia",
"id": 2,
"last_name": "Parker",
},
Object {
"first_name": "Jimmy",
"id": 3,
"last_name": "Robinson",
},
Object {
"first_name": "Zack",
"id": 4,
"last_name": "Carter",
},
Object {
"first_name": "Brad",
"id": 5,
"last_name": "Rayburn",
},
Object {
"first_name": "Ashley",
"id": 6,
"last_name": "Foster",
},
Object {
"first_name": "Parker",
"id": 7,
"last_name": "Trotter",
},
Object {
"first_name": "Kevin",
"id": 8,
"last_name": "Carter",
},
Object {
"first_name": "Zack",
"id": 9,
"last_name": "Klein",
},
]
Last Visible (Retrieve Data)
Object {
"first_name": "Zack",
"id": 9,
"last_name": "Klein",
}
console.log:retrieveMore(直到附加查询为止)
Retrieving additional Data
Previous State: Document Data
Array [
Object {
"first_name": "Kristin",
"id": 1,
"last_name": "Smith",
},
Object {
"first_name": "Olivia",
"id": 2,
"last_name": "Parker",
},
Object {
"first_name": "Jimmy",
"id": 3,
"last_name": "Robinson",
},
Object {
"first_name": "Zack",
"id": 4,
"last_name": "Carter",
},
Object {
"first_name": "Brad",
"id": 5,
"last_name": "Rayburn",
},
Object {
"first_name": "Ashley",
"id": 6,
"last_name": "Foster",
},
Object {
"first_name": "Parker",
"id": 7,
"last_name": "Trotter",
},
Object {
"first_name": "Kevin",
"id": 8,
"last_name": "Carter",
},
Object {
"first_name": "Zack",
"id": 9,
"last_name": "Klein",
},
]
Previous State: Last Visible (Works Up Until Here. lastVisible works, but it doesn't work as the starting point for the additionalQuery)
Object {
"first_name": "Zack",
"id": 9,
"last_name": "Klein",
}
Document Data (Retrieve More) (Post 2nd Query)
Array []
Last Visible (Retrieve More) (Post 2nd Query)
undefined