Using callback ref to modify scrollLeft property in React

Viewed 2777

I've got a container div with a lot of children, and an overflow-x set to scroll.

This allows me to scroll the content to the left and right using my trackpad (or drag on mobile).

But I really would like the default scroll position to be the maximum horizontal value. (i.e. scrolled all the way to the right). The relevant code for this is Element.scrollLeft = <some large value>.

I'm trying to figure out how to achieve this with React and callback refs. I have the following code:

const containerRef = useCallback(
  (node) => {
    if (node !== null) {
      node.scrollLeft = values.length * 20;
    }
  },
  [values.length]
);
return (
    <div className={"scroll-wrapper"} ref={containerRef}>
      values.map(()=>{
        // Some stuff in here that's irrelevant.
      });
    </div>
)

(This code was based on https://reactjs.org/docs/hooks-faq.html#how-can-i-measure-a-dom-node)

When I put a breakpoint in the useCallback function, I see it is properly invoked with a non-0 value, but right after the call when I inspect node.scrollLeft it is still 0.

When I inspect the DOM in Chrome, I can actually force the scrollLeft of the element to be high number, which does work.

So why doesn't the React useCallback ref work?

1 Answers

You should use useRef hook to work with refs.

To create ref use this:

const containerRef = useRef();

And add it to ref of div as you did before:

<div className={"scroll-wrapper"} ref={containerRef}>
  ...
</div>

And you should use useEffect and call it one time to set scrollLeft to the component in ref:

useEffect(() => {
  ref.current.scrollLeft = 4000;
}, []);

Here is the full example: https://codesandbox.io/s/lingering-glitter-s0gok?file=/src/App.js

Related