0

Here is my code:

const [scollPosition, setSrollPosition] = useState(0);

const handleScroll = () => {
  const position = window.pageYOffset;
  console.log(position);
  if (position > scollPosition) {
    console.log("down");
  } else {
    console.log("up");
  }
  setSrollPosition(position);
};

useEffect(() => {
  window.addEventListener("scroll", handleScroll, { passive: true });
  return () => window.removeEventListener("scroll", handleScroll);
}, []);

But it doesn't work, because setSrollPosition(position) didn't update the value of scollPositon.

ZygD
  • 22,092
  • 39
  • 79
  • 102

1 Answers1

0

It's the nature of Reactjs's state, it's updated asynchronously

For your case, use useRef() instead, so you won't need to care about the thing above:

const scollPosition = useRef(0);

  const handleScroll = () => {
    const position = window.pageYOffset;
    console.log(position);
    if (position > scollPosition.current) {
      console.log("down");
    } else {
      console.log("up");
    }
    scollPosition.current = position;
  };

  useEffect(() => {
    window.addEventListener("scroll", handleScroll, { passive: true });
    return () => window.removeEventListener("scroll", handleScroll);
  }, []);

Working example:

function App() {
  const scollPosition = React.useRef(0);

  const handleScroll = () => {
    const position = window.pageYOffset;
    console.log(position);
    if (position > scollPosition.current) {
      console.log("down");
    } else {
      console.log("up");
    }
    scollPosition.current = position;
  };

  React.useEffect(() => {
    window.addEventListener("scroll", handleScroll, { passive: true });
    return () => window.removeEventListener("scroll", handleScroll);
  }, []);
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <h2>Start editing to see some magic happen!</h2>
      <h2>Start editing to see some magic happen!</h2>
      <h2>Start editing to see some magic happen!</h2>
      <h2>Start editing to see some magic happen!</h2>
      <h2>Start editing to see some magic happen!</h2>
      <h2>Start editing to see some magic happen!</h2>
      <h2>Start editing to see some magic happen!</h2>
      <h2>Start editing to see some magic happen!</h2>
      <h2>Start editing to see some magic happen!</h2>
      <h2>Start editing to see some magic happen!</h2>
      <h2>Start editing to see some magic happen!</h2>
      <h2>Start editing to see some magic happen!</h2>
      <h2>Start editing to see some magic happen!</h2>
      <h2>Start editing to see some magic happen!</h2>
      <h2>Start editing to see some magic happen!</h2>
      <h2>Start editing to see some magic happen!</h2>
      <h2>Start editing to see some magic happen!</h2>
      <h2>Start editing to see some magic happen!</h2>
      <h2>Start editing to see some magic happen!</h2>
      <h2>Start editing to see some magic happen!</h2>
      <h2>Start editing to see some magic happen!</h2>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div>
<div id="root"></div>
Ryan Le
  • 7,708
  • 1
  • 13
  • 23