4

I'm using react-transition-group to animate a router switch in React:

    <CSSTransitionGroup transitionName="zoom" transitionEnterTimeout={200} transitionLeaveTimeout={200}>
        <Switch key={key} location={this.props.location}>
            <Route path={this.props.match.url+"/tasks/:task_id"} component={SingleTask} key={'none'} />
            <Route slug={this.props.match.params.project_slug} path={this.props.match.url+"/"} render={(params) => (
                <ProjectIndex {...params} slug={this.props.match.params.project_slug} />
            )} key={'none'}  />
        </Switch>
    </CSSTransitionGroup>

It was also triggering the animation whenever any sub-routes change. So, to get around that I'm getting the pathname using this.props.location.pathname, then using some really gross code to get the last segment:

pathname = pathname.split('?')[0].split('/').filter(function (i) { return i !== ""}).slice(-1)[0];

...and if it's 'tasks', 'activity' or 'notes, I'm just setting the key to 'noanimate' (i.e some generic string so the switch doesn't notice):

    switch(pathname){
        case 'tasks':
        case 'activity':
        case 'notes':
            key = 'noanimate';
            break;
        default:
            key = pathname;
            break;
    }

Now, the redirect from /project to /project/tasks does a double transition as it goes from 'project' to 'noanimate', and I'm not sure whether I'm meant to write some even worse string manipulation just to get either the last or second-last term, depending on whether it's 'tasks'/'activity'/'notes' or any other string.

Is there a better solution, or is that... just how we're meant to do things?

MitchEff
  • 1,417
  • 14
  • 29

1 Answers1

0

I had the same problem so I wrote my own solution: switch-css-transition-group

after install you can rewrite your code to:

import SwitchCSSTransitionGroup from 'switch-css-transition-group'

<SwitchCSSTransitionGroup location={this.props.location} transitionName="zoom" transitionEnterTimeout={200} transitionLeaveTimeout={200}>
    <Route path={this.props.match.url+"/tasks/:task_id"} component={SingleTask} key={'none'} />
    <Route slug={this.props.match.params.project_slug} path={this.props.match.url+"/"} render={(params) => (
        <ProjectIndex {...params} slug={this.props.match.params.project_slug} />
    )} key={'none'}  />
</SwitchCSSTransitionGroup>

It basically go throw all routes inside this "Switch" and using matchPath function recognize if some route is properly matching.

Melounek
  • 764
  • 4
  • 20