amplify-js: understanding React SignOut hoc - doesn't work until reload

Now that there’s a SignOut hoc in aws-amplify-react 1.0.x I tried a simple test by inserting it as a component in a fresh create-react-app App.js (that is also wrapped by withAuthenticator)

If I click the “Sign Out” button that it creates nothing happens - the authData and authState are not affected until I manually reload the page in the browser, they they’re cleared.

Am I misunderstanding that the point of this component to fully trigger a signout sequence, including a rerender or redirect once the state is updated? If not why not just build your own call to Auth.signOut() that includes the rerender or redirect?

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 7
  • Comments: 17 (5 by maintainers)

Most upvoted comments

When using <AmplifySignOut />, a user is redirected to the login page after signing out. This is the expected UX. However, when using Auth.signOut() this does not happen. It would be convenient if there was an option when calling signOut to trigger the same behavior.

@powerful23 Thanks, you made my day! Unfortunately I think the “Amplify Team” should have a look at this - either adding your information to their docs, or by changing the Auth.signOut() method.

Proposed change to the Auth.signOut() method: Add an argument/flag, which allows the user to completely sign out the user when using a single-page application using withAuthenticator or Authenticator. It should be unnecessary for the developer to have to add the extra code as mentioned in the example above.

Hi, here is how I handle it (I had to read aws-amplify-react code to understand the behavior)

I use a react context to have a reference on the method to change state of the Authenticator

class App extends Component {
  static propTypes = {
    onStateChange: PropTypes.func,
  };

  render() {
    return (
      <ThemeProvider theme={theme} key="main">
        <UserContext.Provider
          value={{
            onStateChange: this.props.onStateChange,
          }}
        >
          <Router>
            <Home path="/" />
          </Router>
        </UserContext.Provider>
      </ThemeProvider>
    );
  }
}


export default withAuthenticator(App, false, [
  <Greetings key="greetings" />, //checks if the user is already connected
  <SignIn key="signin" />, //sign in
  <ConfirmSignIn key="confirmSignin" />, //added to customize next one
  <RequireNewPassword key="requireNewPassword" />, //new password is required
]);
Then I get back the method on sign out button


     signOut = onStateChange => async () => {
             await Auth.signOut();
            onStateChange('signedOut');
       };


      render = () => (
               <UserContext.Consumer>
                    {({ onStateChange }) => (
                      <button
                        className="disconnect"
                        onClick={this.signOut(onStateChange)}
                      >
                        Se déconnecter
                      </button>
                    )}
                  </UserContext.Consumer>
       )

An redirect works fine.

First time I used amplify it was with react native. I was very surprise with amplify-react behavior. On react native I did not have to make all this stuff.

So the current workaround is to reload your app like this?

const signOut = async () => {
    try {
        await Auth.signOut();
        window.location.reload();
    } catch (error) {
        console.log('error signing out: ', error);
    }
};

@jonasao Auth.signOut() only clears the tokens stored in cache. In order to change the state back to signIn when using withAuthenticator or Authenticator, you need to do something like:

Auth.signOut().then(() => {
      if (this.props.onStateChange) { this.props.onStateChange('signIn', null); }
});

@jonasao I agree we need either enhance the doc or we can make the Authenticator listen on the Hub event so that when a signOut event emitted from the library, it will change the state back to signIn.

Any update on this? I think everyone can agree both the direct API and component should have a similar UX.