Moaaz Bhnas
Moaaz Bhnas

Reputation: 1179

setState hook not updating

I have a header that I want to hide on scroll down and show on scroll up.
To do that, I saved the scrolling position as prevScrollPos in the state to compare it to the current scrolling position onscroll, and then update prevScrollPos to the current:

 const [visible, setVisible] = React.useState(true);
 const [prevScrollPos, setPrevScrollPos] = React.useState(window.pageYOffset);

  const handleScroll = () => {
    const scrollPos = window.pageYOffset;
    const visible = scrollPos < prevScrollPos;

    setVisible(visible);
    setPrevScrollPos(scrollPos);
  }

The problem is that, for some reason PrevScrollPos doesn't get updated.
Pen: https://codepen.io/moaaz_bs/pen/jgGRoj?editors=0110

Upvotes: 1

Views: 853

Answers (2)

grenzbotin
grenzbotin

Reputation: 2565

You need to modify your useEffect function:

  React.useEffect(() => {
    window.addEventListener('scroll', handleScroll);
    return () => {
      window.removeEventListener('scroll', handleScroll);
    };
  });

Basically you don't have access to prevScrollPos in your handler, therefore prevScrollPos inside the listener will always return 0. To solve this, the dependency array should not be present.

-> + Do not forget to remove the event listener after adding it. :-)

Upvotes: 3

Merci Dieu KIMPOLO
Merci Dieu KIMPOLO

Reputation: 443

Can you try this:

 const [visible, setVisible] = React.useState(true);
 const [prevScrollPos, setPrevScrollPos] = React.useState(window.pageYOffset);

  const handleScroll = () => {
    const scrollPos = window.pageYOffset;
    const visible_new = scrollPos < prevScrollPos;

    setVisible(visible_new);
    setPrevScrollPos(scrollPos);
  }

Upvotes: 0

Related Questions