本文介绍了ReactJs:如何在渲染之前等待componentDidMount()完成?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在渲染之前等待异步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
   ...
}

componentDidMount调用此异步函数:

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

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

解决方案

在渲染前不要等待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');
         }
      });
   });
}

您可以按如下方式使用现有的isAuthenticating标志:

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

然后在内部渲染:

render() {
   if (this.state.isAuthenticating) return null;
   ...
}

这将防止您的组件在authUser函数完成之前被添加到DOM.

How to wait for async componentDidMount() to finish before rendering?

My 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
   ...
}

componentDidMount calls this async function:

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

How can I make the render method wait for authUser() in componentDidMount?

解决方案

Don't wait for componentDidMount to finish before rendering, that would be a misuse of the library, wait for your authUser to finish.

You can do that by utilising your isAuthenticating state property in combination with promises.

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

You could use your existing isAuthenticating flag as follows:

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

Then inside render:

render() {
   if (this.state.isAuthenticating) return null;
   ...
}

This will prevent your component from being added to the DOM until your authUser function completes.

这篇关于ReactJs:如何在渲染之前等待componentDidMount()完成?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-09 23:05