Search code examples
javascripthtmlreactjs

How to scroll the document before a list of divs is rendered on the screen?


<div key={"parent-div"}>
  <div key={"child-div-1"}></div>
  <div key={"child-div-2"}></div>
  <div key={"child-div-3"}></div>
  <div key={"child-div-4"}></div>
  <div key={"child-div-5"}></div>
</div>

The above React component will overflow the viewpoint.

Task: before the component is rendered on the screen, I want child-div-3 to be scrolled to the top.

If the parent div is rendered on the screen first and then the scrolling takes place, then there will be a slight visual glitch. This is what I want to prevent.


Solution

  • You want to run something before the screen is actually painted, but you need the result of rendering before you do this. You can use useLayoutEffect.

    1. Create a ref using useRef pointing to the div.
    2. Use scrollIntoView to scroll to the div in an effect. (Do this before paint)

    You can also create a hook for this:

    const useScrollToDivTop = () => {
      const divRef = useRef();
    
      useLayoutEffect(() => {
        divRef.current.scrollIntoView();
      }, []);
    
      return { divRef };
    };
    
    export default function App() {
      const { divRef } = useScrollToDivTop();
      return (
        <div key={"parent-div"} className="parent-div">
          <div key={"child-div-1"}>1</div>
          <div key={"child-div-2"}>2</div>
    
          <div ref={divRef} key={"child-div-3"}>
            3
          </div>
          <div key={"child-div-4"}>4</div>
          <div key={"child-div-5"}>5</div>
        </div>
      );
    }
    

    Sandbox