Skip to content

<Switch> does not update inside <Suspense> #7137

Closed
@overlookmotel

Description

@overlookmotel

Version

5.1.2 (not tested on previous versions)

Test Case

https://codesandbox.io/s/react-router-t0ig4

Steps to reproduce

Please see above CodeSandbox.

Expected Behavior

Using React Router with Suspense/lazy.

const Home = () => <div>I am not lazy loaded</div>;
const About = React.lazy( () => import('./About.js') );

const App = () => (
  <Router>
    <div>
      <Link to="/">Home</Link>
      <Link to="/about">About</Link>
    </div>
    <Suspense fallback="Loading...">
      <Switch>
        <Route exact path="/" component={Home} />
        <Route path="/about" component={About} />
      </Switch>
    </Suspense>
  </Router>
);

Home is a normal component, About is lazy-loaded.

When you click "About" link, "Loading..." should appear (it does).

Now, while About is still loading, if you click "Home" link, the page should update immediately and show you the "Home" page again.

Actual Behavior

In fact, the route transition back to "Home" is delayed until About has finished loading.

This is hard to spot in a dev environment, as About will load quickly anyway. So in the CodeSandbox above I've substituted a fake Lazy component which never loads. The result is that the page is stuck on "Loading..." forever - navigation ceases to work.

Two things solve the problem:

  1. Add a useLocation() somewhere below the <Switch> element to force <Switch> to re-render on a route transition.
  2. Remove the <Switch> entirely. If it's just a series of <Route> elements, it works as expected.

I have played around with this a lot, and can't figure out if it's a bug in React Router, or in React's handling of Context within Suspense. But I figured I'd post this here first.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions