react-custom-scrollbars
react-custom-scrollbars copied to clipboard
Adapt to children's changes in dimension
The Scrollbars component doesn't react to changes in the height (and I assume width) of its children until the user starts scrolling. This is a problem for content that can have its dimensions change dynamically. For instance, I have a file tree that the user can expand many levels down and as it gets expanded, it eventually overflows the container. At the moment, the scrollthumb doesn't appear until the user starts scrolling using the mousewheel. What is worse is that once the user starts closing the file tree, as it shrinks, the scrollthumb doesn't disappear even though the content is no longer scrollable.
I have managed to find a solution for my own usecase by using react-measure to watch the changes in the dimensions of the children and then triggering a state change to rerender the scrollbars component.
However, it would be best if the scrollbars component handled this internally as it would match the behavior of the browsers' scrollbars.
P.S. for the sake of others who may have the same issue, here's what I did with react-measure to solve the problem:
<Scrollbars
{...this.props}
>
<Measure
onMeasure={dimensions => this.setState({dimensions})}
>
<div>
{this.props.children}
</div>
</Measure>
</Scrollbars>
Yes, thanks for mentioning. You need to ensure that a rerender is triggered from the Scrollbars component down to its children.
Hi,
I got the same problem with a treeview component which does not re render scrollbar when expanding/collapsing nodes. What do you mean by ensure "that a rerender is triggered from the Scrollbars component down to its children" ? Could you please explain in details how you would do it.
Thanks
You need to ensure that not just the children are rerendered but also the Scrollbars component.
@malte-wessel wouldn't it be better if the Scrollbars component handled its own rerender when its contents changed in height or width? As it stands, I have created my own wrapper around the Scrollbars component and use that instead.
@amirmohsen yes, actually this would be cool. But since the Resize Observer API is in an early stage, I don't want to ship this library with the polyfill. The polyfill actually just listens for the window resize event and then checks the dimensions of all observed elements. I guess this is not really performant. For now I would encourage people to use react-measure.
Easiest option for now is to force an update on the scrollbar element inside the callback of the resizing event:
this.scrollbarElement.forceUpdate();
(given that scrollbarElement is a ref to Scrollbars )
I have created a component like this and it works:
import React, { useRef } from 'react';
import Measure from 'react-measure';
import { Scrollbars } from 'react-custom-scrollbars';
const Scrollbar: React.FC = ({ children }) => {
const ScrollbarsRef = useRef<any>(null);
return (
<Scrollbars
ref={ScrollbarsRef}
>
<Measure
bounds
onResize={() => {
ScrollbarsRef.current && ScrollbarsRef.current.forceUpdate();
}}
>
{({ measureRef }) => <div ref={measureRef}>{children}</div>}
</Measure>
</Scrollbars>
);
};
export default Scrollbar;