Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Children routes components remount every route change #83

Open
silviodeligios opened this issue Aug 31, 2019 · 9 comments
Open

Children routes components remount every route change #83

silviodeligios opened this issue Aug 31, 2019 · 9 comments
Labels
bug

Comments

@silviodeligios
Copy link

@silviodeligios silviodeligios commented Aug 31, 2019

I'm using the example in the documentation

import React, {useEffect} from 'react'
import {FocusStyleManager} from '@blueprintjs/core'
import {A, useRoutes} from 'hookrouter'

const AboutArea = () => {
  const routeResult = useRoutes({
    '/people': () => 'We are happy people',
    '/company': () => 'Our company is nice',
  })

  useEffect(() => {console.log('AboutArea mounted')}, [])

  return (
    <div className="about">
      <A href="people">About people</A>
      <A href="company">About our company</A>
      {routeResult}
    </div>
  )
}

const App = () => {
  const routeResult = useRoutes({
    '/': () => 'Home',
    '/about*': () => <AboutArea/>,
  })

  useEffect(() => {console.log('App mounted')}, [])

  return (
    <div>
      <A href="/about/people">Show about area</A>
      {routeResult || 404}
    </div>
  )
}
export default App

If you try to change route the AboutArea component will mount on every route change.
This is a problem in the moment that I want to make api calls in the AboutArea component and share results with children.
am I doing something wrong or is an issue?

@StallionV
Copy link

@StallionV StallionV commented Sep 4, 2019

#61 (comment)

This has been raised before and should be seriously considered given the drawbacks

@Paratron
Copy link
Owner

@Paratron Paratron commented Sep 5, 2019

Sorry, I had responded by mail a couple of days ago already - sadly my mail response appearently did not may its way here. But here is my original response:

Without having looked deeply into your code: a huge warning sign is that you are re-creating new route objects upon each render of your components.

Always declare your route objects as constants outside of your components. Its been written that way in the example as well - and there is even a note about this in the docs.

I am 90% sure this will make your problem go away.

@jmich
Copy link

@jmich jmich commented Sep 18, 2019

Hi Paratron, thanks for maintaining this project :-)

I'm having the same problem and it's not only due to re-creating new route objects.

There was a change in router.js (8f3a178 - Do performance optimizations ).
Here the resultFunc and resultProps were removed from

  • the assignment to the stackObj (line 301 + 302) in process()
  • construction of stackObj (line 343 + 345) in useRoutes()

As far as I can see this means that those are always null in process() now and the effect is that

  • funcsDiffer is always true
  • propsDiffer is always true
  • setUpdate(Date.now()); will always be called by the end of process() and that will re-mount components on every route change

Please have a look at this :-)

@jmich
Copy link

@jmich jmich commented Sep 18, 2019

Downgrading to 1.2.0 (which is before the mentioned change) solves the problem

@Paratron
Copy link
Owner

@Paratron Paratron commented Sep 18, 2019

Thanks for pointing this out. I'll have a look.

@clintharris
Copy link

@clintharris clintharris commented Nov 8, 2019

Having the same problem; downgrading to 1.2.0 also fixed it for me. I realize that in some cases performance hit is negligible, but when it comes to this like using CSS transitions for child components it becomes a deal-breaker issue.

@Paratron Paratron added the bug label Nov 8, 2019
@dvdvdmt
Copy link

@dvdvdmt dvdvdmt commented Jan 22, 2020

This bug bit me too late. I have routes in constants outside of function components. And nested routing produces re-rendering of the parent component when I switch to one of its sub-routes. And downgrading to 1.2.0 doesn't helps.

@JoshVazq
Copy link

@JoshVazq JoshVazq commented Feb 4, 2020

Same problem here. Downgrading to 1.2.0 also fixed it for me.
I love this library and would be nice to know if we are doing something wrong...

Here is a basic example of the problem in codesandbox.io
If you navigate to "/about" page renders the current time and switching between "/people" and "company" remounts AboutPage.
If you change the dependency version from 1.2.3 -> 1.2.0 the parent component is not re-mounted on route changed anymore.

@stefanbugge
Copy link

@stefanbugge stefanbugge commented Jun 18, 2020

If downgrading to 1.2.0 doesn't help then see if some ancestor component is using usePath() without the active parameter set to false.

From the docs

The hook will automatically render the component again, if the path changes. If you don't need that, you can use the hook in passive mode: usePath(false) and it just returns the current path when the component renders and does not trigger renders upon path change.

https://github.com/Paratron/hookrouter/blob/master/src-docs/pages/en/04_other-features.md#using-the-uri-path

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
8 participants
You can’t perform that action at this time.