remix-run / history

Manage session history with JavaScript
MIT License
8.3k stars 961 forks source link

Understanding of use of flag forceNextPop inside createHashHistory.js #770

Open kangka29 opened 4 years ago

kangka29 commented 4 years ago

We have been using HashRouter in our project with getUserConfirmation. We have been facing an issue related to navigation blocking where the callback passed to getUserConfirmation is invoked every alternate attempt. To find the cause, we digged into this library.

Our understanding of the flag forceNextPop inside createHashHistory.js is that every alternate attempt to cancel navigation will be ignored as in the below code. forceNextPop is set to true from revertPop method.

  function handlePop(location) {
    if (forceNextPop) {
      forceNextPop = false;
      setState();
    } else {
      const action = 'POP';

      transitionManager.confirmTransitionTo(
        location,
        action,
        getUserConfirmation,
        ok => {
          if (ok) {
            setState({ action, location });
          } else {
            revertPop(location);
          }
        }
      );
    }
  }

However, if the current history state is the first entry in history stack, the above behavior doesn't apply as indicated by the if condition evaluating delta variable (delta evaluates to false if 0).

  function revertPop(fromLocation) {
    const toLocation = history.location;

    // TODO: We could probably make this more reliable by
    // keeping a list of paths we've seen in sessionStorage.
    // Instead, we just default to 0 for paths we don't know.

    let toIndex = allPaths.lastIndexOf(createPath(toLocation));

    if (toIndex === -1) toIndex = 0;

    let fromIndex = allPaths.lastIndexOf(createPath(fromLocation));

    if (fromIndex === -1) fromIndex = 0;

    const delta = toIndex - fromIndex;

    if (delta) {
      forceNextPop = true;
      go(delta);
    }
  }

Correct us if our understanding is correct as well as if this is the expected behavior.

kangka29 commented 4 years ago

Forgot to mention, we press Cancel whenever the confirmation box comes up when we try to navigate away from the page.