当您单击分页按钮时,以下代码将返回未处理的承诺拒绝'cannot read property 'lastVisiblePost' of undefined
的错误。
似乎在执行初始getPosts
之后立即将状态设置为null。
它在第一次运行时有效,但是当您按下调用getPosts
状态的按钮时,将等于null
。
class App extends Component {
state = {
listState: 'top',
allPosts: [],
lastVisiblePost: null
}
async componentDidMount() {
const { user } = await firebase.auth().signInAnonymously()
this.getPosts()
}
async getPosts() {
console.log(this.state)
console.log(this.state.lastVisiblePost)
let posts = null
if (this.state.lastVisiblePost) {
posts = await firebase.firestore()
.collection('posts')
.orderBy('likes')
.startAfter(last)
.limit(2)
.get()
} else {
posts = await firebase.firestore()
.collection('posts')
.orderBy('likes')
.limit(2)
.get()
}
let newPosts = []
posts.forEach(post => {
newPosts.push({
id: post.id,
data: post.data()
})
})
console.log(posts.docs)
console.log("memes", posts.docs[posts.docs.length - 1])
this.setState({
allPosts: newPosts,
lastVisiblePost: posts.docs[posts.docs.length - 1]
}, () => {
console.log("doink", this.state)
})
}
render() {
const { listState, allPosts } = this.state
return (
<SafeAreaView style={styles.container}>
{ /* Logo */ }
<View style={styles.logoContainer}>
<Image style={styles.logo} source={anywayLogo} />
</View>
{ /* Top and New Buttons */ }
<View style={styles.topAndNewContainer}>
<Text style={[styles.topAndNewText, listState === 'top' ? { color: 'red' } : { color: 'black' }]} onPress={() => this.setState({listState: 'top'})}>top</Text>
<Text style={[styles.topAndNewText, listState === 'new' ? { color: 'red' } : { color: 'black' }]} onPress={() => this.setState({listState: 'new'})}>new</Text>
</View>
{ /* Feed */ }
<View style={styles.feedContainer}>
{
allPosts.map(post => {
return (<Text key={post.id}>{post.data.title}</Text>)
})
}
</View>
<Button title="Next page" onPress={this.getPosts} />
</SafeAreaView>
);
}
}
异步正在等待破坏我的状态吗?
答案 0 :(得分:1)
这是因为您的getPosts
函数未正确绑定到您的组件,因此this
指的是getPosts
函数,而不是您的组件。由于它没有任何状态属性,因此会出现错误。
有两种方法可以执行此操作,或者将其绑定到构造函数中:
class App extends Component {
constructor(props){
super(props)
this.state = {
listState: 'top',
allPosts: [],
lastVisiblePost: null
}
this.getPosts = this.getPosts.bind(this)
}
}
或者您使用transform-class-properties
babel插件,然后可以将组件方法声明为箭头函数,这些函数不提供自己的this
,因此this
关键字将自动引用您的组件:
getPosts = async () => {
//your code
}
答案 1 :(得分:0)
您需要在构造函数中设置状态,否则不会在其余函数中定义状态。
constructor(props) {
super(props);
this.state = {
listState: 'top',
allPosts: [],
lastVisiblePost: null
}
}