React-transition-group: Using react-transition-group with react-router shows redirect warning

Created on 27 Feb 2018  路  6Comments  路  Source: reactjs/react-transition-group

Trying to animate between routes will return a warning in case I'm using some kind of auth. I don't know if I'm doing something wrong or it is some kind of bug. If I remove and it will work without the warning:

class App extends Component {
  state = {
    loggedIn: true
  };

  render() {
    return (
      <div className="App">
        <button onClick={() => this.setState({ loggedIn: !this.state.loggedIn })}>Toggle Login</button>

        <Router>
          <div>
            <ul>
              <li>
                <Link to="/">Home</Link>
              </li>
              <li>
                <Link to="/page2">Page Two</Link>
              </li>
              <li>
                <Link to="/page3">Page Three</Link>
              </li>
            </ul>
            <Route
              render={({ location }) => (
                <TransitionGroup>
                  <CSSTransition key={location.key} classNames="pageChange" timeout={1000}>
                    <Switch location={location}>
                      <Route
                        exact
                        path="/"
                        render={props =>
                          !this.state.loggedIn ? (
                            <PageOne />
                          ) : (
                            <div>
                              <Redirect to="/page2" />
                            </div>
                          )
                        }
                      />
                      <Route
                        path="/page2"
                        render={props =>
                          this.state.loggedIn ? (
                            <PageTwo />
                          ) : (
                            <div>
                              <Redirect to="/" />
                            </div>
                          )
                        }
                      />
                      <Route path="/page3" component={PageThree} />
                    </Switch>
                  </CSSTransition>
                </TransitionGroup>
              )}
            />
          </div>
        </Router>
      </div>
    );
  }
}

Most helpful comment

I think this happens because react-transition-group is trying to apply an exit transition to the Redirect element. A workaround is to prevent re-rendering it if a redirect is happening:

const Workaround = ({ action, children }) =>
  action === 'REPLACE' ? null : children

// ...

<Route
  render={({ location, history }) => (
    <TransitionGroup>
      <CSSTransition
        key={location.key}
        classNames="pageChange"
        timeout={1000}
      >
        <Switch location={location}>
          <Route
            exact
            path="/"
            render={() =>
              !loggedIn ? < PageOne /> : (
                <Workaround action={history.action}>
                  <Redirect to="/page2" />
                </Workaround>
              )
            }
          />
        </Switch>
      </CSSTransition>
    </TransitionGroup>
  )}
/>

All 6 comments

I'm having the same problem. I coded a little demo to better show the problem (have a look at the warnings in the console): https://codesandbox.io/s/13pykjo0wl

Basically, the Switch needs to be provided with this.props.location, as it is immutable (unlike the history.location that it's used by default).
This guarantees that, during a transition to a new route, the page that is transitioning out still holds on the previous route.

Unfortunately, this seems to cause the warning when using Redirect: if the page that is transitioning out contains a Redirect, this page will keep triggering a route redirect, as its location will still hold on the old route.

I haven't found a solution yet for this issue. I also opened a related issue in the React Router repo.

Confirming this issue. Experiencing the same symptoms when trying to redirect within a transition group.

When will the problem be fixed? already passed a lot of time, and it was never fixed!!!

Just found this issue today, i found a quick solution by put the this.props.history.push('/url-location'); in componentDidUpdate. So, it will be like this:

componentDidUpdate(){

    if(this.state.loggedIn) {

        this.props.history.push('/page2');

    }

}

Having this issue as well. Works fine without the TransitionGroup & CSSTransition wrappers.

I think this happens because react-transition-group is trying to apply an exit transition to the Redirect element. A workaround is to prevent re-rendering it if a redirect is happening:

const Workaround = ({ action, children }) =>
  action === 'REPLACE' ? null : children

// ...

<Route
  render={({ location, history }) => (
    <TransitionGroup>
      <CSSTransition
        key={location.key}
        classNames="pageChange"
        timeout={1000}
      >
        <Switch location={location}>
          <Route
            exact
            path="/"
            render={() =>
              !loggedIn ? < PageOne /> : (
                <Workaround action={history.action}>
                  <Redirect to="/page2" />
                </Workaround>
              )
            }
          />
        </Switch>
      </CSSTransition>
    </TransitionGroup>
  )}
/>
Was this page helpful?
0 / 5 - 0 ratings