score:1

The solution to your problem could look as follows:

sandbox

First create a custom usePrevious hook. This is just another function which uses the new useRef method to store the previous scroll value and only updates it when a new value is passed to it.

// Hook
function usePrevious(value) {
  // The ref object is a generic container whose current property is mutable ...
  // ... and can hold any value, similar to an instance property on a class
  const ref = useRef();
  
  // Store current value in ref
  useEffect(() => {
    ref.current = value;
  }, [value]); // Only re-run if value changes
  
  // Return previous value (happens before update in useEffect above)
  return ref.current;
}

In the actual component we declare a previousPosition variable. Every time the component re-renders, the our customHook is executed with the current position. It returns the previous position which then gets assigned.

Also with each render, the useEffect method is being executed, as we do not pass an Array as second argument. There we just compare the current scroll position with the previous and scroll back to the previous in case it changed.

function Scroll(props){
  const prevPosition = usePrevious(window.pageYOffset);
   // Update scoll position with each update
   useEffect(() => {
     if(window.pageYOffset !== prevPosition){
         window.scrollTo(0, prevPosition);
     }  
   });

   return (
      <div>
      ...
      </div>
   );
}

score:1

If I understand correctly, use useLayoutEffect instead of useEffect. This will scroll back to the top before the component is rendered. Remember to add the dependency array.


Related Query

More Query from same tag