【问题标题】:React async function resets state to null after setStateReact async 函数在 setState 之后将状态重置为 null
【发布时间】:2019-04-11 09:07:01
【问题描述】:

当您单击分页按钮时,以下代码将针对未处理的 Promise 拒绝 '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>
        );
    }
}

async await 会破坏我的状态吗?

【问题讨论】:

    标签: javascript reactjs react-native asynchronous async-await


    【解决方案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
    }
    

    【讨论】:

    • 你明白了 - 第二个是问题,我搞砸了函数声明语法 - 太棒了!
    • 要明确第一个或第二个都可以,但第二个是 imo 更好的语法。请记住,无论何时您需要通过this 引用您的组件,您的方法都应该正确绑定。很高兴我能帮上忙!
    【解决方案2】:

    您需要在构造函数中设置状态,否则它不会在您的其余函数中定义。

    constructor(props) {
       super(props);
       this.state = {
        listState: 'top',
        allPosts: [],
        lastVisiblePost: null
       }
    }
    

    【讨论】:

    • 在第 2 行使用state 设置
    • 你需要在构造函数中进行。
    猜你喜欢
    • 2020-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-18
    • 1970-01-01
    • 2016-11-09
    相关资源
    最近更新 更多