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

Prevent remount component on routes with the same component #5430

Conversation

artywhite
Copy link
Contributor

@artywhite artywhite commented Aug 12, 2017

Prevents remount component on routes with the same component.

This issue was described and fixed for react-router here: #4578 , but for react-router-config this bug occurs again due different key value on <Route> component.

Since <Switch> renders only one component there is no need to use unique key prop for <Route>.

Not sure if this is right fix, but it works.

)}/>
{routes.map(route => (
<Route
key='prevent-remount-and-use-static-key'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you make this shorter? Seems a waste to put a long string here just to remind devs. key='fixed' would also work, no?

Copy link
Contributor

@pshrmn pshrmn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't really ideal because it forces all routes to have the same key. What happens if the user wants a re-mount to happen? I think that a better approach would be to allow route objects to have a key property and then prefer that over index

<Route key={route.key || i} ... />

@artywhite
Copy link
Contributor Author

Added support for key property in route objects

@timdorr timdorr merged commit f1a600b into remix-run:master Aug 21, 2017
@artywhite
Copy link
Contributor Author

Thank you guys! Any thoughts when these changes will be released?

@KaroseLiu
Copy link

I'm not sure, this commit fixed the bug, I upgraded the latest version v4.2.0 as your release, and try it, the component also remount.

@KaroseLiu
Copy link

KaroseLiu commented Aug 30, 2017

Here is my layout:

const Layout = ({children, location}) => {
  // url like /:personId/a, /:personId/b
  const personId = location.pathname.split('/')[2]
  // b or a path
  const activeKey = location.pathname.split('/')[3]
  // The problem is every time the path changed, the Profile always componentDidMount.
  return <div>
    <Profile personId={personId}/>
    <Tabs
      type="card"
      activeKey={location.pathname.split('/')[3]}
      onTabClick={(key) => {
        const paths = location.pathname.split('/')
        history.push(`/person/${personId}/${key}`)
      }}
    >
      {tabs.map(tab =>
        (<TabPane tab={tab.title} key={tab.key}>
          {children}
        </TabPane>),
      )}
    </Tabs>
  </div>
}

The below is the Router config:

const routes = [
  {
    path: '/a',
    component: A,
  },
  {
    path: '/b',
    component: B,
  },
  {
    path: '/c',
    component: C,
  },
]
const Router = ({ match }) => (
  <Switch>
    {
      routes.map(({ path, exact, strict, component: Comp }) =>
        (<Route
          key={path}
          path={`${match.url}${path}`}
          exact={exact}
          strict={strict}
          render={
            props => (
              <Layout {...props}>
                <Comp {...props} />
              </Layout>
            )
          }
        />),
      )
    }
  </Switch>
)

Every time the path change, the component will didMount again, so maybe my usage is the incorrect way to reuse the layout?

@wmertens
Copy link
Contributor

wmertens commented Aug 30, 2017 via email

@KaroseLiu
Copy link

The above layout, The LEFT container is person Profile and The RIGHT is the change things belong to the path changed component(A, B, C).

Every time url change, the component always remounting. In my mind, the Profile component should not remount when path changed.

const Layout = ({children, location}) => {
  return <div>
    // The Profile component will remounting when path changed. 
    <Profile personId={personId}/>
    <Tabs
      type="card"
      activeKey={location.pathname.split('/')[3]}
      onTabClick={(key) => {
        const paths = location.pathname.split('/')
        history.push(`/person/${personId}/${key}`)
      }}
    >
      {tabs.map(tab =>
        (<TabPane tab={tab.title} key={tab.key}>
          {children}
        </TabPane>),
      )}
    </Tabs>
  </div>
}

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants