2

Can anybody tell me why I am getting this.setState is not defined error in the code below?

componentDidMount(){
    firebase.auth().onAuthStateChanged(function(user) {
        if (user) {
            this.setState({user:user});
            console.log(user.uid);
        } else {
            this.setState({user:null});
            console.log("logged out");
        }
      });
}

I tried different approaches also:

componentDidMount(){
    firebase.auth().onAuthStateChanged(function(user) {
        if (user) {
            //this.setState({user:user});
            this.sState(user);
            console.log(user.uid);
        } else {
            this.setState({user:null});
            console.log("logged out");
        }
      });
}
sState(user){
    this.setState({user:user});
}

For the above, the error is this.sState is not a function.

I checked out the similar questions in SO they don't seem to be helpful in my case. Thanks..

KENdi
  • 7,576
  • 2
  • 16
  • 31
honor
  • 7,378
  • 10
  • 48
  • 76

1 Answers1

1

Either use Arrow functions or bind the onAuthStageChanged to the components

firebase.auth().onAuthStateChanged((user) => {
    if (user) {
        //this.setState({user:user});
        this.sState(user);
        console.log(user.uid);
    } else {
        this.setState({user:null});
        console.log("logged out");
    }
});

Arrow functions bind automatically to this, normal functions does not

Are 'Arrow Functions' and 'Functions' equivalent / exchangeable?

EDIT Using bind over a function. Basically when the function is called, assigns 'this' operator to the bind argument.

componentDidMount(){
    firebase
       .auth()
       .onAuthStateChanged(this.authStateChangeHandler.bind(this));
}

authStateChangeHandler(user) {
    if (user) {
        this.setState({user:user});
        console.log(user.uid);
     } else {
        this.setState({user:null});
        console.log("logged out");
     }
}

jgoday
  • 2,768
  • 1
  • 18
  • 17
  • this seems to work. thanks, @jgoday. Can you also add the code snippet for the part you say "or bind the onAuthStageChanged to the components"? How do we do that exactly? how do I achieve this without the arrow function? – honor Mar 20 '19 at 20:25
  • thanks for the edit. Now I realize that when we bind a method with .bind(this), we don't need to explicitly pass an argument to the bound function (in this case authStateChangeHandler) but it automatically gains access to the returned user object from firebase. How would you explain this? – honor Mar 21 '19 at 16:49