4

I'm looking for a way to "cosmetically" update the route in the address bar of a React/Redux/React-Router/React-Router-Redux application, without actually causing the component to remount when the route changes.

I'm using React CSS Transition Groups to animate entering a route. So when the user goes from

/home/

to

/home/profile/bob,

an animation fires.

However, once on /home/profile/bob, the user can swipe left/right to get to other profiles -- /home/profile/joe etc.

I want the URL in the address bar to update when this happens, but currently that causes the profile component to re-mount, which re-triggers the CSS Transition Group, causing the animation to trigger -- I only want that animation to trigger when going from a non-profile route to a profile route, not when switching between profile routes.

I hope this makes sense. I'm essentially looking for a way to "cosmetically" update the app URL without forcing a re-mounting of the component which manages that route.

tdc
  • 5,174
  • 12
  • 53
  • 102

2 Answers2

1

If you are using react router, it will mount/unmount when you change the url. That's the normal behaviour. It's the same thing for transitioning between pages, you can only declare and in/out transition without knowing from which url path did you come from :(

Michael Rasoahaingo
  • 1,069
  • 6
  • 11
0

I've attempt to achieve what your talking about. I could prevent a full-page transition when moving between 'child-routes' but I haven't been able to trigger a specific transition for the child routes (due to the parent route re-rendering). Here's what I came up with https://codesandbox.io/s/Dkwyg654k.

import React, { Component } from 'react';
import { render } from 'react-dom';
import { BrowserRouter as Router, Route, Switch, Link } from 'react-router-dom';
import { CSSTransitionGroup } from 'react-transition-group';

import About  from './components/About';
import Home   from './components/Home';
import Topics from './components/Topics';

import './styles.css';

var currentRoute = ''

const getParentPathname = pathname => 
  pathname === '/'
    ? ''
    : (/([a-zA-Z])([^/]*)/).exec(pathname)[0]

class BasicExample extends Component {
  render = () =>
    <Router>
      <Route
        render={({ location, history, match }) => {

          const nextRoute = getParentPathname(location.pathname)
          const isParentRouteChange = 
                !currentRoute.includes(nextRoute) || 
                !nextRoute.includes(currentRoute)
          currentRoute = nextRoute

          return(
            <div>
              <ul>
                <li>
                  <Link to="/">Home</Link>
                </li>
                <li>
                  <Link to="/about">About</Link>
                </li>
                <li>
                  <Link to="/topics">Topics</Link>
                </li>
              </ul>

              <hr />
              <CSSTransitionGroup
//                 transitionEnter={isParentRouteChange}
//                 transitionLeave={isParentRouteChange}
                transitionEnterTimeout={500}
                transitionLeaveTimeout={500}
                transitionName={isParentRouteChange ? "fade" : "slide"}
              >
                <Switch key={location.key} location={location}>
                  <Route exact path="/"       component={Home}   location={location} key={location.key}/>
                  <Route       path="/about"  component={About}  location={location} key={location.key}/>
                  <Route       path="/topics" component={Topics} location={location} key={location.key}/>
                </Switch>
              </CSSTransitionGroup>
            </div> 
          )

        }
      }/>
    </Router>

}

render(<BasicExample />, document.body)
Brad Woods
  • 1,507
  • 2
  • 12
  • 30