React Native + TypeScript, can't set State

2.7k Views Asked by At

I know my functioning is running but for whatever reason I can't set the state of this property "isLoggedIn"

In the componentDidMount() I setState based on login detection and it doesn't seem to work.

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 {
   isLoggedIn?: boolean;
}

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() {

      firestack.auth.listenForAuth((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);

        }

        if (!this.isLoggedIn) {

            Actions.welcome();

        }


    }); 

}

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);

Anything that I'm doing wrong?

2

There are 2 best solutions below

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

This code will not work. setState is asynchronous, so this.isLoggedIn is not necessarily updated immediately after you call setState. If you want to access the new value immediately, use the callback that triggers when the state is set:

this.setState({ isLoggedIn: false }, () => console.log(this.state.isLoggedIn));

Or, use this method of setting the state:

this.setState(oldState => {
    oldState.isLoggedIn = false;

    console.log(oldState.isLoggedIn);
    return oldState;
}); 
0
On

Fetch data in componentDidMount. When the response arrives, store the data in state by calling setstate inside callback.

componentDidMount() is invoked immediately after a component is mounted. Initialization that requires DOM nodes should go here. If you need to load data from a remote endpoint, this is a good place to instantiate the network request. Setting state in this method will trigger a re-rendering.