question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Improve docs when using dynamic routes under Route component

See original GitHub issue

I could be misunderstanding some interaction here, but if what I’ve observed is true, then I’ve encountered a pitfall which I believe needs to be documented more.

In the project I work on I have effective this:

        <Router history={history}>
            <Switch>
                <Route name="foo" path={`/foo`} component={FooComponent} />
                <Route component={({ match }) => <BarComponent />} />
            </Switch>
        </Router>

The BarComponent contains a list of Routes which are code split (which shouldn’t matter for this)

        <div>
            <Header />
            <Sidebar />
            <Container>
                <Switch>
                    <Route name="a1" path={`/a1`} component={({ match }) => <AuthenticationWrapper componentName="A1" match={match} />} />
                    <Route name="a2" path={`/a2`} component={({ match }) => <AuthenticationWrapper componentName="A2" match={match} />} />
                </Switch>
            </Container>
        </div>

And now here is the problem. Within A2 there are tabs in that component, I handle the tables by a declarative route:

                <Route path={`/a2/:tab`} children={({match, ...rest}) => {

Long story short, whenever I clicked a tab, which contained a react-router-dom Link, I noticed every single component under the dynamic route (and in reality probably the top level Route) was being re-mounted (componentDidMount being called).

So after digging into the react-router docs I saw that when defining a Route with component, which I do at the top level:

When you use component (instead of render, below) the router uses React.createElement to create a new React element from the given component. That means if you provide an inline function, you are creating a new component every render. This results in the existing component unmounting and the new component mounting instead of just updating the existing component. For inline rendering, use the render prop (below).

What I did then, at the top level is instead of using component with the a2 component, I switched it to render and now no more re-mounts. I’m still not entirely clear that this is the right approach.

If this really is the right approach, and RRv4 is meant to be used with dynamic routing, then shouldn’t the docs be very explicit in the children and render Route section and also in the example? From an outside perspective, it took a lot of searching in the issues section + docs + trial and error to finally realize that maybe I shouldn’t be using component at the top level. Nearly every example out there uses component instead of render at the top level, so it makes it a bit confusing. It looks like: https://reacttraining.com/react-router/web/example/animated-transitions uses render at the top level, while using dynamic routing below, which makes sense now, but there is no explanation of that in the example itself, or why it was used that way.

Apologies for being long winded, I hope that by logging this issue I can also save some other people time when dealing with this issue as well. Having the entire sub-tree re-mounted on each route change, due to dynamic routes, is a performance killer.

So maybe, correct me if I’m wrong, what I’m looking for is confirmation and addition to the docs to the effect of: “If a top level Route ultimately contains dynamic Routes under it, then that top level Route should use render instead of component otherwise all children will be re-mounted when the url changes”.

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:13 (5 by maintainers)

github_iconTop GitHub Comments

2reactions
timdorrcommented, Jun 26, 2017

It’s not so much that it’s supported, but more that it’s possible, so folks will do it. And there’s nothing invalid about that pattern, it’s just weird.

It will also commonly happen if they have some sort of async loading component, which will change the component once it loads. That would be where I’d see this more likely to happen.

1reaction
engineersamuelcommented, Jun 2, 2017

Let me make one correction to the above, it appears that by simply avoiding the () => ... anonymous function within <Route component /> that the re-mounting is avoided. I think my request above then is still valid, this should be clarified, especially when using dynamic routing as it can cause a lot of re-renders.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Improve docs when using dynamic routes under ... - GitHub
Long story short, whenever I clicked a tab, which contained a react-router-dom Link , I noticed every single component under the dynamic route...
Read more >
How To Handle Routing in React Apps with React Router
In this step, you'll use URL queries and parameters to create dynamic routes. You'll learn how to pull information from search parameters with...
Read more >
How to achieve Dynamic routing in React Router 4?
By writing the Route path of the component Article as ... import React from 'react' import { BrowserRouter as Router, Route, Link, ...
Read more >
Dynamic Routes - Next.js
Dynamic Routes are pages that allow you to add custom params to your URLs. ... However, route parameters will override query parameters with...
Read more >
A guide to using React Router v6 in React apps
This new element is an upgrade of the previous Switch component. It includes features like relative routing and linking, automatic route ranking ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found