I have a simple page transition that gets called when clicking a link. The new page animates from the bottom of the screen upwards to the top. It works fine, but it's also working when you click the back button in the browser. I don't want the transition to fire if someone clicks the back button on the browser, I just want to go back to the page at whatever scrolled position I left it in, in exactly the same way you would expect to happen by clicking the browser back button.
If I take the CSS transitions off then the back button works fine, so I need to somehow differentiate between the back button being clicked and a link being clicked and then play the transition accordingly.
I don't know if I need to setState or something else? I did try that, but it seemed to set the state variable after the transition had happened.
import React, { useEffect, useState } from 'react';
import {Route, NavLink, Switch, useHistory } from "react-router-dom";
import './App.css';
import Home from './Home';
import About from './About';
import { CSSTransition, TransitionGroup,} from 'react-transition-group';
const usePageMeta = (title, description) =>{
const defaultTitle = "app-name";
const defaultDesc = "meta description";
useEffect(() => {
document.title = title || defaultTitle;
document.querySelector("meta[name='description']").setAttribute("content", description || defaultDesc);
}, [defaultTitl
e, title, defaultDesc, description]);
};
const App = () =>{
return (
<div className="App">
<div className="nav fixed top-0 left-0 z-10 w-full">
<NavLink exact to="/" activeClassName="active">Home</NavLink>
<NavLink to="/about" activeClassName="active">About</NavLink>
</div>
<Route render={({location}) => (
<TransitionGroup>
<CSSTransition
key={location.key}
timeout={1000}
classNames="fade"
>
<Switch location={location}>
<Route exact path="/">
<Home usePageMeta={usePageMeta}/>
</Route>
<Route path="/about">
<About usePageMeta={usePageMeta}/>
</Route>
</Switch>
</CSSTransition>
</TransitionGroup>
)} />
</div>
);
}
export default App;
Can anyone point me in the right direction please?
After some testing, I can see that this is bound to happen as the path is being loaded into the history of the browser.
tl;dr This is not a quirk of the library, its just the way the browsers work. The current session always pushes state on the history object. To prevent this you can do two things
Solution 1:
history.createHref(history.location)Solution 2:
Note: this is assuming the user has to be navigated to the site which came from.
Edit: Solution 2 is refactored to use the 'history' package utilities. This is seen more appropriate as the browser states are not touched with react code.
Also in the docs, it was mentioned that the history object is mutable which does result in some problems with mounting.
Caveat: this solution goes through all the states in between where the user is and where they started from, so expect some flashes of the earlier components.
Solution 1 also uses the same package, with the caveat that it will go to the first page and then goBack() 1 page more. This will be less of a flash then solution 2.