user16468845
user16468845

Reputation:

Execute code on Back Button Click (REACTJS)

Below code is execute when I browse one page to another page for example. when I click on a product from the category page listing, the below code sets a session storage key that will have a position of the category page (how much page has been scrolled).

So when the product page will open it saves its key in session & if again it visited the same category page it restore the page position.

I am trying to make this code save only one session key & remove the previously saved session key regardless of which page the user clicks on the website (i.e category page, product 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));
   }
 }, []);

any thoughts on this to remove the previous session key?

Upvotes: 10

Views: 734

Answers (2)

GalAbra
GalAbra

Reputation: 5148

What I understand is upon loading a page, you want to:

  1. If this page was the last visited page: load its saved location.
  2. Else: remove the last saved location and save it upon scrolling.

Then it looks like you need to save some sort of page ID with the location you're saving/loading. This unique identifier can clearly be the URL.

Then, you can use a similar version of your code:

 const [scrollPosition, setScrollPosition] = React.useState('');
 const getPathname = () => document.location.pathname.substr(1);

 React.useEffect(() => {
   if (window) {
     window.onscroll = function (e) {
       setScrollPosition(window.scrollY);
       if (scrollPosition != 0) {
         const savedPosition = { position: scrollPosition, pathName: getPathname() };
         sessionStorage.setItem('scrollPosition', JSON.stringify(savedPosition));
       }
     };
   }
 }, [scrollPosition]);

 React.useEffect(() => {
   const lastSavedPosition = JSON.parse(sessionStorage.getItem('scrollPosition'));
   if (window && lastSavedPosition && getPathname() === lastSavedPosition.pathName) {
      $(window).scrollTop(lastSavedPosition.position);
      console.log(`position_set to = ${lastSavedPosition.position}`);
   }
 }, []);

Upvotes: 3

If you are using redux with react you can actually make a reducer that tracks location by sending actions that contain the information if the user was on the product page.

Something like this:

So if you have few routes like:

/category/house/3213124(product_id)
/category/garden/dsfsdfs(product_id)

In your router you can adress them like this:

/category/house/{id}
/category/garden/{id}

Then you can use :

let { id } = useParams();

if(id !== undefined || ""){
     dispatch(userIsOnProductPageAction(true))
}

When users click the back button by using a selector for reducer you have information that was a user on the product page... if true execute code, if false do nothing.

Also after executing code you dispatch userIsOnProductPageAction(false).

If you are not using redux, you can apply the same logic but problem is that you have to hold the state wasUserOnPage and somehow access it when on the category page.

Since I don't know how your React application looks I can't tell you how to achieve that. If the product is a child element and the category is a parent element by clicking the back button you could probably send that information through props.

EDIT: it should look something like this

    class main extends React.Component {
  constructor(props) {
    super(props)

    this.handler = this.handler.bind(this)
  }

  handler() {
    this.setState({
      wasOnProductPage:false
    })
  }

  render() {
    return <Category handler = {this.handler} props={this.props.wasOnProductPage} />
            <Product handler = {this.handler} />
  }
}

class Category extends React.Component {
  render() {

    if(props){
        do code for viewport
        then acitave this.props.handler and set it to false
    }
  }
}

class Product extends React.Component {
  render() {
    return <BackButton onClick = {this.props.handler(true)}/ >
  }
}

Upvotes: 4

Related Questions