-3

I have my method

authHandler(authData){

    if(!this.isMounted())
        return;

    const storeRef = myDatabase.ref(this.props.storeId);

    storeRef.once('value', (snapshot) => {
        const data = snapshot.val() || {};

        if(!data.owner){
            storeRef.set({
                owner: authData.user.uid
            });
        }

        this.setState({
            uid: authData.user.uid,
            owner: data.owner || authData.user.uid
        });

        // localStorage.setItem(`authData-${this.props.storeId}`, JSON.stringify(authData));
    });
}

and here is the componentDidMount()

   componentDidMount(){

    app.auth().onAuthStateChanged(function(user, error){
        if(!error && this.handleErrors){
            this.handleErrors(error);
            return;
        }

        if(user){
            console.log(user);
            this.authHandler(user);
        }
    });
}

But no matter what I do, it always throws:

TypeError: this.authHandler is not a function

I read through some similar questions: e.g. ReactJS - this.functionname is not a function

but none of them work for me.

halfer
  • 19,824
  • 17
  • 99
  • 186
Franva
  • 6,565
  • 23
  • 79
  • 144
  • 1
    Use an arrow function for the event handler. – Andrew Li Aug 07 '17 at 18:15
  • @AndrewLi thanks, this works for me can you please explain the reason? thanks – Franva Aug 08 '17 at 04:22
  • 1
    See the link. TLDR regular function expressions have their `this` set by how they're called. Usually, `this` will refer to `window` inside a regular function expression in a callback because of how they're called. Arrow functions do not bind their own `this`. The `this` value inside an arrow function refers to the `this` from the enclosing scope. Thus `this` inside an arrow function will refer to the component, not `window`. – Andrew Li Aug 08 '17 at 04:24

1 Answers1

-1

Just use arrow function:

 componentDidMount(){

    app.auth().onAuthStateChanged((user, error) => {
        if(!error && this.handleErrors){
            this.handleErrors(error);
            return;
        }

        if(user){
            console.log(user);
            this.authHandler(user);
        }
    });
}
Alex Borodin
  • 1,555
  • 12
  • 26
  • Thanks Alexander, it works for me :) But can you please explain the reason? thanks – Franva Aug 08 '17 at 04:21
  • 1
    Arrows functions have "lexical scoping" instead of "dynamical" so you will get your class as "this" instead of other class or function. You can read here about it https://derickbailey.com/2015/09/28/do-es6-arrow-functions-really-solve-this-in-javascript/ – Alex Borodin Aug 08 '17 at 11:43
  • beautiful, thanks~! – Franva Aug 08 '17 at 12:41