ReactJs:如何在渲染之前等待componentDidMount()完成?

Sti*_*iño 7 firebase reactjs

如何等待异步componentDidMount()在渲染之前完成?

我的app.jsx:

constructor(props) {
    super(props);

    this.state = {
        loggedInUser: null,
        isAuthenticated: false,
        isAuthenticating: true
    };
}

componentDidMount() {
    try {
        var user = authUser();
        console.log('User: ' + user)
        if (user) {
            console.log('Is logged in: ' + this.state.loggedInUser)
            this.userHasAuthenticated(true);  
        }
    }
    catch(e) {
       alert(e);
    }
    this.setState({ isAuthenticating: false });
}

render() { 
   console.log('in render: ' + this.state.loggedInUser)
   // Should execute **after** authUser() in componentDidMount has finished  
   ...
}
Run Code Online (Sandbox Code Playgroud)

componentDidMount调用此异步函数:

function authUser() {
    firebase.auth().onAuthStateChanged(function(user) {
        return user
    })
}
console.log('in render: ' + this.state.loggedInUser)
Run Code Online (Sandbox Code Playgroud)

如何让render方法等待componentDidMount中的authUser()?

lin*_*new 16

componentDidMount在渲染之前不要等待完成,这将是对库的误用,等待你authUser完成.

你可以通过结合使用你的isAuthenticating州财产来做到这一点promises.

function authUser() {
   return new Promise(function (resolve, reject) {
      firebase.auth().onAuthStateChanged(function(user) {
         if (user) {
            resolve(user);
         } else {
            reject('User not logged in');
         }             
      });
   });
}
Run Code Online (Sandbox Code Playgroud)

您可以使用现有isAuthenticating标志,如下所示:

componentDidMount() {
    authUser().then((user) => {
       this.userHasAuthenticated(true);
       this.setState({ isAuthenticating: false });
    }, (error) => {
       this.setState({ isAuthenticating: false });
       alert(e);
    });
}
Run Code Online (Sandbox Code Playgroud)

然后在里面渲染:

render() {
   if (this.state.isAuthenticating) return null;
   ...
}
Run Code Online (Sandbox Code Playgroud)

这将阻止您的组件添加到DOM,直到您的authUser功能完成.