#506·wouter

Re-rendering the component for a source route after navigating to a destination route in a promise

Author: elanmedCreated Jan 27, 2025Updated Jan 12, 2026

Issue

When navigating from a source route (i.e. /route-a) to a destination route (/route-b) after a promise, the component for the source route is re-rendered after the navigation - when the URL is already set to the destination.

Reproducing

I was able to reproduce this issue in a code sandbox: https://codesandbox.io/p/sandbox/exciting-wilson-l9sk9x

typescript
export default function App() {
  return (
    <Router>
      <Switch>
        <Route path="/" component={Root} />
        <Route path="/route-a" component={PageA} />
        <Route path="/route-b" component={PageB} />
      </Switch>
    </Router>
  );
}

function PageA() {
  console.log("PageA render, pathname:", window.location.pathname);
  return (
    <div>
      <p>page A</p>
      <button
        onClick={() => {
          Promise.resolve().then(() => {
            navigate("/route-b");
          });
        }}
      >
        navigate after promise
      </button>
      <button
        onClick={() => {
          navigate("/route-b");
        }}
      >
        navigate immediately
      </button>
    </div>
  );
}

function PageB() {
  return <div>page B</div>;
}

function Root() {
  return (
    <div>
      <h1>Steps to repro</h1>
      ...
    </div>
  );
}
  • Go to /route-a
  • Open the console
  • Click navigate after promise

The console will read:

PageA render, pathname: /route-a
PageA render, pathname: /route-b

This is unexpected, since PageA should only render on /route-a, not /route-b

If you repro with the following steps, the extra render does not occur:

  • Go to /route-a
  • Open the console
  • Click navigate immediately

The console will only read:

PageA render, pathname: /route-a

Which is what I would expect in both cases.

Why this is an issue

Say I have a condition in PageA to check for a search param (i.e. auth=1), and if it does not exist, navigate to an earlier route where the search param is populated. When navigating from /route-a to /route-b, I don't include the search param i.e. I would navigate from /route-a?auth=1 to /route-b , not /route-b?auth=1. When navigating after promise, PageA is re-rendered with the URL of /route-b. Since the auth=1 search param is not present, my condition kicks in, and I'm navigated away from the destination route. This is more or less the scenario that led me to root-cause this issue.

Notes