Is their any way we can observer back button click in react ?
Actually, i have added a code on category page, the functionality it provides is to remain the user anchored on page.
For example : customer browse category page scroll through products & click product page then click back button then user see exactly the same category page products which user clicked (i.e same product position).
For this i set below code on category page
CategoryPage.js
const [scrollPosition, setScrollPosition] = React.useState('');
React.useEffect(() => {
var pathName = document.location.pathname.substr(1);
if (window) {
window.onscroll = function (e) {
setScrollPosition(window.scrollY);
if(scrollPosition != 0){
sessionStorage.setItem("scrollPosition_"+pathName, scrollPosition);
}
};
}
}, [scrollPosition]);
React.useEffect(() => {
var pathName = document.location.pathname.substr(1);
if (window && sessionStorage.getItem("scrollPosition_"+pathName)) {
$(window).scrollTop(sessionStorage.getItem('scrollPosition_'+ pathName));
console.log('position_set to = ' + sessionStorage.getItem('scrollPosition_'+ pathName));
}
}, []);
As you can see code scrollTop the screen with value saved in session storage
It works but i need this thing to work only when this scenario
(i.e user visit category page, scroll through page, click product, product page opens & click back button)
It should not work with any other scenario like (user visit category page, scroll through page, click product, product page opens, user click another page or homepage & visit Same category page & with above code it scrolls it to the same page's position).
Solution : Check the previous route is product page then scroll top else do nothing
is their any fix for this ? how to check the previous route is product page ?
We can observe a back button click, by listening to the history object. Try the below example,
import { useHistory } from 'react-router-dom';
const Test = () => {
const history = useHistory();
useEffect(() => {
return () => {
if (history.action === "POP") {
}
};
}, [history])
}
event POP would mean, back button click.
Ref:- https://reactrouter.com/web/api/history
You could get to know the previous page through location history
import { useHistory } from 'react-router-dom';
const Test = () => {
const history = useHistory();
useEffect(() => {
return history.listen(location => {
if (history.action === 'POP') {
}
})
}, [])
}
location.from will give you the previous route.
Update in response to comments:
I see you're using next/router which has beforePopState for this, it takes a callback and if that cb returns false, then router will not do anything for the POP event.
Ref: https://nextjs.org/docs/api-reference/next/router#routerbeforepopstate
Keep the route history i.e, pathname or asPath in a global state and thereby you could find out if the previous route was product page and on back button click (beforePopState) you could execute your code.
You can't observe what a user is doing in the browser app itself (i.e. clicking the back button), but you can listen for "popstate" events. https://developer.mozilla.org/en-US/docs/Web/API/History_API#examples In React you can use history.
I think you'll find instantiating a history object and using it to listen will be easier for you.
import { createBrowserHistory } from 'history';
const history = createBrowserHistory();
const useBackListener = (callback) => {
const listener = (location, action) => {
if (action === "POP") {
// back navigation
callback(location, action);
}
};
useEffect(() => {
const unlisten = history.listen(listener);
return unlisten;
}, []);
return path;
};