Search code examples
javascriptreact-nativeaws-amplify

AWS Amplify: onStatusChange then render main page


I am trying to render the main entry point of my application when an auth status change occurs but when I do try to go to the main entry point of my application I get a blank screen. I'm assuming I can't go to a main page if it isn't being called within the render function itself? If so, how do I render the main Page of my app when I established signIn?

index.js

class App extends Component {

  /*
  constructor(props) {
    super(props);
    this.state = {
        authState: null,
        authData: null
    }
}
*/
handleAuthStateChange(state) {
  alert(state)
  if (state === 'signedIn') { 
    alert('here');
    return ( // go To Entry point of app
      <ApolloProvider store={store} client={client}>
      <AppWithNavigationState/>
      </ApolloProvider>
    );
  }
}

    render() {
      //const { authState, authData } = this.state;
     // const signedIn = (authState === 'signedIn');


        return (
         <Authenticator hideDefault={true} onStateChange={this.handleAuthStateChange}>
        <Login/>
        </Authenticator>

      );
    }

}
export default App = codePush(App);

Login.js

export default class Login extends Component {


    render() {

       const { authState, onStateChange } = this.props;

       if (!['signIn', 'signedOut', 'signedUp'].includes(authState)) {
           alert('login')
        return null;
       }


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

            <View style={styles.backgroundContainer}>
            <Image source={images.icons.LoginImage} style={styles.backgroundImage} />
            </View>
            <View style={styles.overlay}>
            <Button iconLeft light rounded style={styles.facebookLoginButton}>
            <Icon style={styles.facebookIcon} name='logo-facebook' />
            <Text style={styles.facebookButtonText}>Login with Facebook</Text>
            </Button>
            <Button rounded bordered light style={styles.loginLaterButton}
            onPress={() => onStateChange('signedIn')}>
            <Text style={styles.buttonText}>Sign In Test</Text>
            </Button>


            </View>

            </View>

        );
      }
    }

Solution

  • This is really about rendering and state (and not anything to do with AWS Amplify). First, set up state in your constructor:

    constructor(props) { super(props); this.state = { authState: '' }; }

    Then, your onAuthStateChange() becomes:

    onAuthStateChange(newState) { if (newState === 'signedIn') { this.setState({ authState: newState }); } }

    Finally, in your render() method, you adjust your rendering so that it does "the right thing" based on your auth state.

    render() { if (this.state.authState === 'signedIn') { return (<ApolloProvider ...><MyApp/></ApolloProvider>); } else { return (<Authenticator .../>); } }

    You can abstract this away with a HOC as well (the same way the withAuthenticator() HOC from AWS Amplify does it). Basically, the Authenticator gets displayed initially. Once the signedIn state is received, the internal component state is updated and that causes a re-render of the component with the rest of your app.