Mike P
Mike P

Reputation: 313

React Native w/ TypeScript this.setState is not a function

I'm currently using React Native 0.39.2 w/ newest TypeScript and when I run my componentDidMount() method and setState I get an error around this.setState is not a function.

I tried binding with this.setState({isLoggedIn: true}).bind(this)

though since I'm using a boolean as the type it won't let me without giving a type error and even setting to any type still gets same error.

here's my code

First with my interface for State

import React, {
 Component
} from 'react';
import { AppRegistry, View, StyleSheet, Text } from 'react-native';
import { Actions } from 'react-native-router-flux';

import Firestack from 'react-native-firestack';

const firestack = new Firestack();

interface Props {

}

interface State {
  isLoggedIn?: boolean;
}


export default class MainList extends Component<Props, State> {

   state = {
     isLoggedIn: false,
   };

   constructor(props: any) {

      super(props);
      console.log("Is anyone logged in?: " + this.isLoggedIn);

   }

   isLoggedIn = this.state.isLoggedIn;

   componentDidMount() {

      if (!this.isLoggedIn) {

          Actions.welcome();

      }

      firestack.auth.listenForAuth(function(evt: any) {
      // evt is the authentication event
      // it contains an `error` key for carrying the
      // error message in case of an error
      // and a `user` key upon successful authentication

        if (!evt.authenticated) {
        // There was an error or there is no user
        //console.error(evt.error);

        this.setState({isLoggedIn: false});
        console.log("The state of isLoggedIn is: " +       this.isLoggedIn);

        } else {
        // evt.user contains the user details
        console.log('User details', evt.user);

        this.setState({isLoggedIn: true});
        console.log("The state of isLoggedIn is: " + this.isLoggedIn);

        }


    }); 

}

render() {

    return (
        <View style={styles.View}>

            <Text style={styles.textLabel}>The main view</Text>

        </View>
     )

   }

 }

 const styles = StyleSheet.create({

 View: {
    padding: 20
 },
 textLabel: {
    fontSize: 20,
    marginBottom: 10,
    height: 20
 },
 textInput: {
    height: 20,
    fontSize: 15,
    marginBottom: 20
  }

});

AppRegistry.registerComponent('MainList', ()=> MainList);

Is there anything I'm missing here?

Upvotes: 1

Views: 1384

Answers (1)

max23_
max23_

Reputation: 6689

The issue is because in the callback function for listenForAuth, this is no longer referring to the MainList object.

Try switching to arrow function expression which solve the this binding issue:

firestack.auth.listenForAuth((evt: any) => {
  ...
});

Here is a good read if you want to know more about arrow function.

Upvotes: 3

Related Questions