Search code examples
authenticationreactjsreact-routerfluxhistory.js

`replaceState` not working inside `then` of a Promise


Let's assume that we have an API call authenticates the user and then based on if a user is returned from the server or not, we either replaceState or do nothing, which might look something like this:

<Route component={App} onEnter={authUser} />

const onEnter = (nextState, replaceState) => {
  if (isClient) {
    AuthHelper.findCurrentUser()
      .then(response => {
        // This here doesn't work, `replaceState` doesn't change the page or URL, however I know for sure
        // that the line is being called because if I put a `debugger` right before it,
        // the `debugger` hits every time...
        replaceState({nextPathname: nextState.location.pathname}, '/dashboard');
      })
      .catch(response => {});

    // If we put the same line here, it redirects the user to the dashbaord.
    // replaceState({nextPathname: nextState.location.pathname}, '/dashboard');
  }
}

The only differentiating factor between replaceState working and not working is that one is called from within the then of a Promise, and one is called outside of the Promise resolution. Does the Promise affect replaceState from executing?


Solution

  • The syntax for asynchronous onEnter hooks is necessarily a bit difference, since we need a way to block the transition until the handler has completed running.

    If your onEnter hook is asynchronous, then it needs to take a 3rd argument, e.g.

    function onEnter(nextState, replaceState, callback) {
        /* ... */
    }
    

    When you do this, you have to call callback() yourself when your enter hook has finished running. It's necessary for us to use this API to support people who e.g. aren't using